Back to index

salome-kernel  6.5.0
SALOMETraceCollector.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/SALOMETraceCollector/SALOMETraceCollector.cxx,v 1.9.2.1.10.2.12.1 2012-04-12 14:05:31 vsr Exp $
00027 //
00028 #include <SALOMEconfig.h>
00029 
00030 #include <iostream>
00031 #include <sstream>
00032 #include <fstream>
00033 #include <cstdlib>
00034 #include <omniORB4/CORBA.h>
00035 
00036 #include "SALOMETraceCollector.hxx"
00037 #include "TraceCollector_WaitForServerReadiness.hxx"
00038 #include <SALOMEconfig.h>
00039 #include CORBA_CLIENT_HEADER(Logger)
00040 
00041 // Class attributes initialisation, for class method SALOMETraceCollector::run
00042 
00043 CORBA::ORB_ptr SALOMETraceCollector::_orb = 0;
00044 
00045 // ============================================================================
00053 // ============================================================================
00054 
00055 BaseTraceCollector* SALOMETraceCollector::instance()
00056 {
00057   if (_singleton == 0) // no need of lock when singleton already exists
00058     {
00059       int ret;
00060       ret = pthread_mutex_lock(&_singletonMutex); // acquire lock to be alone
00061       if (_singleton == 0)                     // another thread may have got
00062         {                                      // the lock after the first test
00063           BaseTraceCollector* myInstance = new SALOMETraceCollector();
00064           int argc=0;
00065           char *_argv=0;
00066           char ** argv = &_argv;
00067           _orb = CORBA::ORB_init (argc, argv);
00068 
00069           sem_init(&_sem,0,0); // to wait until run thread is initialized
00070           pthread_t traceThread;
00071           int bid = 0;
00072           pthread_create(&traceThread, NULL,
00073                                    SALOMETraceCollector::run, &bid);
00074           sem_wait(&_sem);
00075           _singleton = myInstance; // _singleton known only when init done
00076         }
00077       ret = pthread_mutex_unlock(&_singletonMutex); // release lock
00078     }
00079   return _singleton;
00080 }
00081 
00082 // ============================================================================
00091 // ============================================================================
00092 
00093 void* SALOMETraceCollector::run(void *bid)
00094 {
00095   _threadId = new pthread_t;
00096   *_threadId = pthread_self();
00097   sem_post(&_sem); // unlock instance
00098 
00099   LocalTraceBufferPool* myTraceBuffer = LocalTraceBufferPool::instance();
00100   LocalTrace_TraceInfo myTrace;
00101 
00102   SALOME_Logger::Logger_var m_pInterfaceLogger;
00103   CORBA::Object_var obj;
00104 
00105   obj = TraceCollector_WaitForServerReadiness(_orb,"Logger");
00106   if (!CORBA::is_nil(obj))
00107     m_pInterfaceLogger = SALOME_Logger::Logger::_narrow(obj);
00108   if (CORBA::is_nil(m_pInterfaceLogger))
00109     {
00110       std::cerr << "Logger server not found ! Abort" << std::endl;
00111       std::cerr << std::flush ; 
00112       exit(1);
00113     } 
00114   else
00115     {
00116       CORBA::String_var LogMsg =
00117         CORBA::string_dup("\n---Init logger trace---\n");
00118       m_pInterfaceLogger->putMessage(LogMsg);
00119       DEVTRACE("Logger server found");
00120     }
00121 
00122   // --- Loop until there is no more buffer to print,
00123   //     and no ask for end from destructor.
00124 
00125   while ((!_threadToClose) || myTraceBuffer->toCollect() )
00126     {
00127       if (_threadToClose)
00128         {
00129           DEVTRACE("SALOMETraceCollector _threadToClose");
00130           //break;
00131         }
00132 
00133       myTraceBuffer->retrieve(myTrace);
00134       if (!CORBA::is_nil(_orb))
00135         {
00136           if (myTrace.traceType == ABORT_MESS)
00137             {
00138               std::stringstream abortMessage("");
00139 #ifndef WIN32
00140               abortMessage << "INTERRUPTION from thread "
00141                            << myTrace.threadId << " : " << myTrace.trace;
00142 #else
00143               abortMessage << "INTERRUPTION from thread "
00144                            << (void*)&myTrace.threadId 
00145                            << " : " << myTrace.trace;
00146 #endif
00147               CORBA::String_var LogMsg =
00148                 CORBA::string_dup(abortMessage.str().c_str());
00149               m_pInterfaceLogger->putMessage(LogMsg);
00150               exit(1);
00151             }
00152           else
00153             {
00154               std::stringstream aMessage("");
00155 #ifndef WIN32
00156               aMessage << "th. " << myTrace.threadId
00157 #else
00158                 aMessage << "th. " << (void*)&myTrace.threadId
00159 #endif
00160                        << " " << myTrace.trace;
00161               CORBA::String_var LogMsg =
00162                 CORBA::string_dup(aMessage.str().c_str());
00163               m_pInterfaceLogger->putMessage(LogMsg);
00164             }
00165         }
00166     }
00167   pthread_exit(NULL);
00168   return NULL;
00169 }
00170 
00171 // ============================================================================
00175 // ============================================================================
00176 
00177 SALOMETraceCollector:: ~SALOMETraceCollector()
00178 {
00179   int ret;
00180   ret = pthread_mutex_lock(&_singletonMutex); // acquire lock to be alone
00181   if (_singleton)
00182     {
00183       DEVTRACE("SALOMETraceCollector:: ~SALOMETraceCollector()");
00184       LocalTraceBufferPool* myTraceBuffer = LocalTraceBufferPool::instance();
00185       _threadToClose = 1;
00186       myTraceBuffer->insert(NORMAL_MESS,"end of trace\n"); // to wake up thread
00187       if (_threadId)
00188         {
00189           int ret = pthread_join(*_threadId, NULL);
00190           if (ret) std::cerr << "error close SALOMETraceCollector : "<< ret << std::endl;
00191           else DEVTRACE("SALOMETraceCollector destruction OK");
00192           delete _threadId;
00193           _threadId = 0;
00194           _threadToClose = 0;
00195         }
00196       _singleton = 0;
00197     }
00198   ret = pthread_mutex_unlock(&_singletonMutex); // release lock
00199 }
00200 
00201 // ============================================================================
00206 // ============================================================================
00207 
00208 SALOMETraceCollector::SALOMETraceCollector()
00209 {
00210   _threadId=0;
00211   _threadToClose = 0;
00212 }
00213 
00214 // ============================================================================
00218 // ============================================================================
00219 
00220 extern "C"
00221 {
00222  SALOMETRACECOLLECTOR_EXPORT
00223   BaseTraceCollector *SingletonInstance(void)
00224   {
00225     BaseTraceCollector *instance = SALOMETraceCollector::instance();
00226     return instance;
00227   }
00228 }