I am writing a logger and would like to make it thread-safe. I have done so by doing the following:
class Logger
{
public:
    virtual ~Logger();
    LogSeverity GetSeverity() const;
    void SetSeverity(LogSeverity s);
protected:
    std::mutex mutex;
private:
    LogSeverity severity;
};
void Logger::SetSeverity(LogSeverity s)
{
    std::lock_guard<std::mutex> lock(mutex);
    severity = s;
}
LogSeverity Logger::GetSeverity() const
{
    std::lock_guard<std::mutex> lock(mutex);
    return severity;
}
void Logger::SetSeverity(LogSeverity s) const
{
    std::lock_guard<std::mutex> lock(mutex);
    severity = s;
}
// StreamLogger inherits from Logger
void StreamLogger::SetStream(ostream* s)
{
    std::lock_guard<std::mutex> lock(mutex);
    stream = s;
}
ostream* StreamLogger::GetStream() const
{
    std::lock_guard<std::mutex> lock(mutex);
    return stream;
}
However, all public access to the class require this extremely redundant lock.
Two options I see:
1) Caller of these public function will lock the whole object using the mutex within the class
Logger l = new Logger();
std::lock_guard<std::mutex> lock(l->lock());
l->SetSeverity(LogDebug);
2) Wrapper lock around each variable in the class
template typename<T> struct synchronized
{
public:    
    synchronized=(const T &val);
    // etc..
private:
    std::mutex lock;
    T v;
};
class Logger
{
private:
    synchronized<LogSeverity> severity;
};
However, this solution is very resource intensive, lock for each item.
Am I on the right track or is there something I am missing?
Aucun commentaire:
Enregistrer un commentaire