2

I should implement a logger for an application and I should use the singleton pattern. Moreover, since this application is multithreaded, this logger should be thread-safe. I would like to point out that I have to use C++03.

I've seen this implementation of singleton pattern in C++/QT using a QMutex static object in order to guarantee that only one thread allocates the unique instance of the singleton object.

Why does everybody return a singleton as a pointer? I would return it as a reference, so I should not worry about explicitly free the memory used by the singleton object. I read this answer and this other answer and I wrote the following implementation.

// ==========
// Logger.h

#include <QMutex>
#include <QString>

class Logger
{
public:
    static Logger& instance();

    void configure(const QString& folder);

private:
    Logger();
    Logger(const Logger&);
    Logger& operator=(const Logger&);

private:
    mutable QMutex _mutex;
    QString _folder;
};


// ==========
// Logger.cpp

Logger::Logger() : _mutex() { ; }

Logger& Logger::instance()
{
    static QMutex mutex;

    mutex.lock();
    static Logger instance;
    mutex.unlock();

    return instance;
}

void Logger::configure(const QString& folder)
{
    _mutex.lock();
    _folder = folder;
    _mutex.unlock();
}

I have some questions...

  1. Is the function instance() thread-safe when the unique instance is created?
  2. At the time of the destruction of the object, will the singleton object destroyed in thread-safe manner?
Community
  • 1
  • 1
enzom83
  • 8,080
  • 10
  • 68
  • 114
  • 1
    A better method would be to have the Logger implement a void Log(const QString&) slot. This allows all objects to emit a Log signal to send to the log and will work across threads. – TheDarkKnight Nov 04 '14 at 12:04
  • @Merlin069: Signals and slots provide a better way to accomplish my goal, but they require an event loop to be running and I noticed that unfortunately some opencv functions (like the `cvShowImage` function) crash when an event loop is running. – enzom83 Nov 04 '14 at 12:19
  • You could pack your instance of the `Logger` class into a `QSharedPointer` which is thread-save for access from different threads. See http://qt-project.org/doc/qt-5/qsharedpointer.html#thread-safety – tomvodi Nov 04 '14 at 12:21
  • For a different, yet interesting, implementation of thread-safety see [QsLog](https://bitbucket.org/razvanpetru/qt-components/wiki/QsLog). – BaCaRoZzo Nov 04 '14 at 12:31
  • @thomas_b: from the linked documentation: "It should be noted that, while the pointer value can be accessed in this manner, QSharedPointer and QWeakPointer provide no guarantee about the object being pointed to." – stefaanv Nov 04 '14 at 12:39

0 Answers0