Back to index

salome-kernel  6.5.0
LocalTraceCollector.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  File   : LocalTraceCollector.cxx
00024 //  Author : Paul RASCLE (EDF)
00025 //  Module : KERNEL
00026 //  $Header: /home/server/cvs/KERNEL/KERNEL_SRC/src/SALOMELocalTrace/LocalTraceCollector.cxx,v 1.10.2.1.10.2.12.1 2012-04-12 14:05:31 vsr Exp $
00027 //
00028 #include <iostream>
00029 #include <sstream>
00030 #include <fstream>
00031 #include <cstdlib>
00032 
00033 #include "LocalTraceCollector.hxx"
00034 
00035 // ============================================================================
00044 // ============================================================================
00045 
00046 BaseTraceCollector* LocalTraceCollector::instance()
00047 {
00048   if (_singleton == 0) // no need of lock when singleton already exists
00049     {
00050       int ret;
00051       ret = pthread_mutex_lock(&_singletonMutex); // acquire lock to be alone
00052       if (_singleton == 0)                     // another thread may have got
00053         {                                      // the lock after the first test
00054           BaseTraceCollector* myInstance = new LocalTraceCollector();
00055 
00056           sem_init(&_sem,0,0); // to wait until run thread is initialized
00057           pthread_t traceThread;
00058           pthread_create(&traceThread, NULL,
00059                                    LocalTraceCollector::run, NULL);
00060           sem_wait(&_sem);
00061           _singleton = myInstance; // _singleton known only when init done
00062         }
00063       ret = pthread_mutex_unlock(&_singletonMutex); // release lock
00064     }
00065   return _singleton;
00066 }
00067 
00068 // ============================================================================
00077 // ============================================================================
00078 
00079 void* LocalTraceCollector::run(void *bid)
00080 {
00081   _threadId = new pthread_t;
00082   *_threadId = pthread_self();
00083   sem_post(&_sem); // unlock instance
00084 
00085   LocalTraceBufferPool* myTraceBuffer = LocalTraceBufferPool::instance();
00086   LocalTrace_TraceInfo myTrace;
00087 
00088   // --- Loop until there is no more buffer to print,
00089   //     and no ask for end from destructor.
00090 
00091   while ((!_threadToClose) || myTraceBuffer->toCollect() )
00092     {
00093       if (_threadToClose)
00094         {
00095           DEVTRACE("FileTraceCollector _threadToClose");
00096           //break;
00097         }
00098 
00099       myTraceBuffer->retrieve(myTrace);
00100       if (myTrace.traceType == ABORT_MESS)
00101         {
00102           std::cout << std::flush ;
00103 #ifndef WIN32
00104           std::cerr << "INTERRUPTION from thread " << myTrace.threadId
00105                << " : " <<  myTrace.trace;
00106 #else
00107           std::cerr << "INTERRUPTION from thread " << (void*)(&myTrace.threadId)
00108                << " : " <<  myTrace.trace;
00109 #endif
00110           std::cerr << std::flush ; 
00111           exit(1);     
00112         }
00113       else
00114         {
00115           std::cout << std::flush ;
00116 #ifndef WIN32
00117           std::cerr << "th. " << myTrace.threadId << " " << myTrace.trace;
00118 #else
00119           std::cerr << "th. " << (void*)(&myTrace.threadId)
00120                << " " << myTrace.trace;
00121 #endif
00122           std::cerr << std::flush ; 
00123         }
00124     }
00125   pthread_exit(NULL);
00126   return NULL;
00127 }
00128 
00129 // ============================================================================
00133 // ============================================================================
00134 
00135 LocalTraceCollector:: ~LocalTraceCollector()
00136 {
00137   int ret;
00138   ret = pthread_mutex_lock(&_singletonMutex); // acquire lock to be alone
00139   if (_singleton)
00140     {
00141       DEVTRACE("LocalTraceCollector:: ~LocalTraceCollector()");
00142       LocalTraceBufferPool* myTraceBuffer = LocalTraceBufferPool::instance();
00143       _threadToClose = 1;
00144       myTraceBuffer->insert(NORMAL_MESS,"end of trace\n"); // to wake up thread
00145       if (_threadId)
00146         {
00147           int ret = pthread_join(*_threadId, NULL);
00148           if (ret) std::cerr << "error close LocalTraceCollector : "<< ret << std::endl;
00149           else DEVTRACE("LocalTraceCollector destruction OK");
00150           delete _threadId;
00151           _threadId = 0;
00152           _threadToClose = 0;
00153         }
00154       _singleton = 0;
00155     }
00156   ret = pthread_mutex_unlock(&_singletonMutex); // release lock
00157 }
00158 
00159 // ============================================================================
00164 // ============================================================================
00165 
00166 LocalTraceCollector::LocalTraceCollector()
00167 {
00168   _threadId=0;
00169   _threadToClose = 0;
00170 }
00171 
00172