I am writing a 'thread-safe' C++ wrapper of C API, while the API itself is NOT internally thread safe. I have tried to use RAII.
I would like to know, is my implementation correct? and whether it is thread safe. I appreciate any comments on my code. Thanks in advance!
The C API to be wrapped is as follows,
/* an data structure which represents a connection proxy to the logger: */
struct cLog_Logger;
/* connect the logger, and returns a handle to it: */
cLog_Logger* cLog_connect();
/* appends a zero terminated string to the log: */
void cLog_write(cLog_Logger* logger, const char* message);
/* closes the connection with the logger: */
void cLog_close(cLog_Logger* logger);
My implementation of the wrapper is as follows:
class LoggerWrapper{
public:
LoggerWrapper(){ //constructor
cLog= cLog_connect();
}
void log(const std::string &message){ //entry point
cLog_write(cLog, message);
cLog_close(cLog);
}
~LoggerWrapper(){ //destructor
delete cLog;
}
protected:
cLog_Logger *cLog;
}
Thanks!
I think you need to change the implementation like this:
class LoggerWrapper{
public:
LoggerWrapper(){ //constructor
cLog= cLog_connect();
}
void log(const std::string &message){ //entry point
cLog_write(cLog, message);
}
~LoggerWrapper(){ //destructor
cLog_close(cLog);
delete cLog;
}
protected:
cLog_Logger *cLog;
} ;
This allows you to write code like this:
LoggerWrapper logger ;
logger.log("Something") ;
logger.log("Something else) ;
so make more than one log with the same object; otherwise the first call closes the logger and the object is useless. Is this what you want?
Then there is the second question: what do you mean by thread safety? Do you want to make logs on the same object from different threads?
Then you can add a mutex and a lock guard inside log function like this:
class LoggerWrapper{
public:
LoggerWrapper(){ //constructor
cLog= cLog_connect();
}
void log(const std::string &message){ //entry point
std::lock_guard<std::mutex> guard(mutex);
cLog_write(cLog, message);
}
~LoggerWrapper(){ //destructor
cLog_close(cLog);
delete cLog;
}
protected:
cLog_Logger *cLog;
std::mutex mutex ;
} ;
Short answer: no it's not. At first, I think there must be free()
instead of delete
, because it's c
api. What you doing can give your resource-leak-free program, but not thread-safe. RAII is for avoiding leak of resources. There is straightforward but inefficient way to wrap your API for thread safe to add static mutex in your RAII class.
#include <mutex>
class LoggerWrapper{
public:
LoggerWrapper() : l(globalLock);
{ //constructor
cLog= cLog_connect();
}
void log(const std::string &message){ //entry point
cLog_write(cLog, message);
cLog_close(cLog);
}
~LoggerWrapper(){ //destructor
free(cLog); // I think here must be free(), but not sure
}
protected:
cLog_Logger *cLog;
static std::mutex globalLock;
std::lock_guard<std::mutex> l;
}
std::mutex LoggerWrapper::globalLock;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.