mardi 28 juillet 2015

C++11 Thread-safe polymorphism with less verbosity

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