Listing 7

// ErrorLogger.h, cpp
class ErrorLogger
{
  // Adds support for background threads
public:
  // ...
  static void SetBgLogger( ErrorLoggerPtr );
protected:
  // ...
  static boost::mutex   mtx_;
private:
  // ...
  static ErrorLoggerPtr bgLogger_;
};
//----------------------------------------------------------
// ErrorLogger.cpp
struct ThreadIdHelper
{
  // Standard singleton setup ...
public:
  bool CurThreadIsForeground()
  {
    boost::thread curThread;
    return curThread == fg_;
  }
private:
  // initializing the Singleton sets fg_ to the thread
  // doing the initialization
  boost::thread fg_;
};
//----------------------------------------------------------
void ErrorLogger::SetBgLogger( ErrorLoggerPtr logger )
  // force ThreadIdHelper::fg_ initialization
  ThreadIdHelper::Instance();
  bgLogger_ = logger;
}
//----------------------------------------------------------
ErrorLoggerPtr ErrorLogger::Instance( )
{
  if( loggers_.empty() )
    PushLogger(ErrorLoggerPtr(new ErrorLogger));
  if( bgLogger_ &&
      !ThreadIdHelper::Instance()->CurThreadIsForeground() )
    return bgLogger_;
  return loggers_.top();
}
//----------------------------------------------------------
void ErrorLogger::Error( const string& msg )
{
  boost::mutex::scoped_lock lock(mtx_);
  cerr << msg;
}