Reputation: 539
I have read articles about double-check which may not be safe with C++ on arbitrary CPU. I am not quite sure whether my codes are absolutely safe or not. Class Database represents database file, and the connection is dynamically created when needed. Database::GetConnection may be called from different threads simultaneously. If the code is not absolutely safe, how can I modify the code. Thank you.
#include <mutex>
#include "sqlite3.h"
class Connection
{
private:
sqlite3* _handle;
std::string _path;
public:
Connection(const std::string& path) : _path(path) {
sqlite3_open(_path.c_str(), &_handle);
// some other initialization work..
}
}
class Database
{
private:
typedef enum
{
Void,
Connected,
// some other status...
} Status;
std::string _path;
std::mutex _mutex;
Status _status;
Connection* _connection;
void OpenDatabase()
{
_connection = new Connection(_path);
_status = Connected;
}
public:
Connection* GetConnection()
{
if (_status == Connected)
return _connection;
std::lock_guard<std::mutex> guard(_mutex);
if (_status != Connected)
OpenDatabase();
return _connection;
}
public:
Database(const std::string& path) : _path(path), _status(Void) {};
};
Upvotes: 0
Views: 108
Reputation: 6752
For efficiency ... is safe enough
You're dealing with a database, efficiency is moot and safe enough is up to you
Enough implies a level of allowable uncertainty. Are you ok with that?
What happens in that 0.001% chance it's not safe enough? Does the software crash? Does the hardware explode? Do birds turn inside out and fall from the sky?
If your OpenDatabase
function is locked everywhere else in your Database
class, then what's wrong with removing the first check and leaving your GetConnection
function as so:
Connection* GetConnection()
{
std::lock_guard<std::mutex> guard(_mutex);
if (_status != Connected)
OpenDatabase();
return _connection;
}
You're dealing with a database, so the few milliseconds it takes to your CPU to create and store the std::lock_guard
and lock/unlock the _mutex
object then preform a simple boolean check is massively insignificant compared to the 100's of milliseconds building a connection and transactional state for the database can take.
Save the birds.
Upvotes: 1