]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
PR: thread safe singleton
authorprascle <prascle>
Tue, 5 Oct 2004 18:36:46 +0000 (18:36 +0000)
committerprascle <prascle>
Tue, 5 Oct 2004 18:36:46 +0000 (18:36 +0000)
src/SALOMELocalTrace/LocalTraceBufferPool.cxx
src/SALOMELocalTrace/LocalTraceBufferPool.hxx
src/SALOMELocalTrace/LocalTraceCollector.cxx
src/SALOMELocalTrace/LocalTraceCollector.hxx

index 67791553f7eccf254d89e669e456ed6f038f4221..49b6d32e6b08e2246104ba6251f248692804e7db 100644 (file)
 using namespace std;
 
 LocalTraceBufferPool* LocalTraceBufferPool::_singleton = 0;
+pthread_mutex_t LocalTraceBufferPool::_singletonMutex;
 
 // ============================================================================
 /*!
- *  guarantees a unique object instance of the class (singleton)
- *  Must be done at first because not thread safe: 
- *  _singleton is not protected by a mutex
+ *  guarantees a unique object instance of the class (singleton thread safe)
  */
 // ============================================================================
 
 LocalTraceBufferPool* LocalTraceBufferPool::instance()
 {
-  if (_singleton == 0) _singleton = new LocalTraceBufferPool();
+  if (_singleton == 0) // no need of lock when singleton already exists
+    {
+      int ret;
+      ret = pthread_mutex_lock(&_singletonMutex); // acquire lock to be alone
+      if (_singleton == 0)                     // another thread may have got
+       {                                      // the lock after the first test
+         _singleton = new LocalTraceBufferPool(); 
+       }
+      ret = pthread_mutex_unlock(&_singletonMutex); // release lock
+    }
   return _singleton;
 }
 
index 8474780058f1cf57d48439220868520bb087deff..597b218e8355343e2865f7fd63995075712ca648 100644 (file)
@@ -57,6 +57,7 @@ class LocalTraceBufferPool
 
  private:
   static LocalTraceBufferPool* _singleton;
+  static pthread_mutex_t _singletonMutex;
   LocalTrace_TraceInfo _myBuffer[TRACE_BUFFER_SIZE];
   sem_t _freeBufferSemaphore;       // to wait until there is a free buffer
   sem_t _fullBufferSemaphore;       // to wait until there is a buffer to print
index 11972264317e1cc92db5f987934c039d0f51de8a..1bf05248ef864a700a87b272762046adcc001ccb 100644 (file)
 using namespace std;
 
 LocalTraceCollector* LocalTraceCollector::_singleton = 0;
+pthread_mutex_t LocalTraceCollector::_singletonMutex;
 int LocalTraceCollector::_threadToClose = 0;
 pthread_t LocalTraceCollector::_threadId = 0;
 int LocalTraceCollector::_toFile = 0;           // public, set by user
 
 // ============================================================================
 /*!
- *  guarantees a unique object instance of the class (singleton)
- *  Must be done at first because not thread safe: 
- *  _singleton is not protected by a mutex
- *  LocalTraceCollector instance is created, then LocalTraceBufferPool
- *  instance is created immediately in the same thread (not thread safe, too).
- *  After thet, a separate thread for loop to print traces is launched.
+ *  guarantees a unique object instance of the class (singleton thread safe)
+ *  a separate thread for loop to print traces is launched.
  */
 // ============================================================================
 
 LocalTraceCollector* LocalTraceCollector::instance()
 {
-  if (_singleton == 0)
+  if (_singleton == 0) // no need of lock when singleton already exists
     {
-      _singleton = new LocalTraceCollector();
-      LocalTraceBufferPool* initTraceBuffer = LocalTraceBufferPool::instance();
-      pthread_t traceThread;
-      int bid;
-      int ret = pthread_create(&traceThread, NULL,
-                              LocalTraceCollector::run, (void *)bid);
+      int ret;
+      ret = pthread_mutex_lock(&_singletonMutex); // acquire lock to be alone
+      if (_singleton == 0)                     // another thread may have got
+       {                                      // the lock after the first test
+         _singleton = new LocalTraceCollector(); 
+         pthread_t traceThread;
+         int bid;
+         int ret = pthread_create(&traceThread, NULL,
+                                  LocalTraceCollector::run, (void *)bid);
+       }
+      ret = pthread_mutex_unlock(&_singletonMutex); // release lock
     }
   return _singleton;
 }
index 5bcd75139c7ec03a50a06fcdafe303172e0fd1ce..0b0e56ff5887f6f5f276aec2eaeb91025da9cacc 100644 (file)
@@ -43,6 +43,7 @@ class LocalTraceCollector
 
  private:
   static LocalTraceCollector* _singleton;
+  static pthread_mutex_t _singletonMutex;
   static pthread_t _threadId;
 };