From 0a9db7de31188582d9445984556cbff8582f9bbd Mon Sep 17 00:00:00 2001 From: prascle Date: Wed, 20 Oct 2004 12:00:21 +0000 Subject: [PATCH] PR: Multithreaded trace, part 2 - with logger --- src/SALOMELocalTrace/LocalTraceBufferPool.cxx | 18 +- src/SALOMELocalTrace/LocalTraceCollector.cxx | 175 +++++++++++++++--- src/SALOMELocalTrace/LocalTraceCollector.hxx | 10 +- .../LocalTrace_WaitForServerReadiness.cxx | 131 +++++++++++++ ... => LocalTrace_WaitForServerReadiness.hxx} | 46 +---- src/SALOMELocalTrace/Makefile.in | 7 +- src/SALOMELocalTrace/SALOME_Log.hxx | 85 --------- 7 files changed, 310 insertions(+), 162 deletions(-) create mode 100644 src/SALOMELocalTrace/LocalTrace_WaitForServerReadiness.cxx rename src/SALOMELocalTrace/{SALOME_Log.cxx => LocalTrace_WaitForServerReadiness.hxx} (55%) delete mode 100644 src/SALOMELocalTrace/SALOME_Log.hxx diff --git a/src/SALOMELocalTrace/LocalTraceBufferPool.cxx b/src/SALOMELocalTrace/LocalTraceBufferPool.cxx index 49b6d32e6..73046c6ec 100644 --- a/src/SALOMELocalTrace/LocalTraceBufferPool.cxx +++ b/src/SALOMELocalTrace/LocalTraceBufferPool.cxx @@ -30,6 +30,10 @@ #include "LocalTraceBufferPool.hxx" #include "utilities.h" +// In case of truncated message, end of trace contains "...\n\0" +#define TRUNCATED_MESSAGE "...\n" +#define MAXMESS_LENGTH MAX_TRACE_LENGTH-5 + using namespace std; LocalTraceBufferPool* LocalTraceBufferPool::_singleton = 0; @@ -85,8 +89,8 @@ int LocalTraceBufferPool::insert(int traceType, const char* msg) strncpy(_myBuffer[myInsertPos%TRACE_BUFFER_SIZE].trace, msg, - MAX_TRACE_LENGTH-1); // last char always 0 even if msg too long - _myBuffer[myInsertPos%TRACE_BUFFER_SIZE].threadId = pthread_self(); // thread id + MAXMESS_LENGTH); // last chars always "...\n\0" if msg too long + _myBuffer[myInsertPos%TRACE_BUFFER_SIZE].threadId =pthread_self();//thread id _myBuffer[myInsertPos%TRACE_BUFFER_SIZE].traceType = traceType; _myBuffer[myInsertPos%TRACE_BUFFER_SIZE].position = myMessageNumber; @@ -129,9 +133,9 @@ int LocalTraceBufferPool::retrieve(LocalTrace_TraceInfo& aTrace) // increment the free buffer semaphore // (if previously 0, awake one of the threads waiting to put a trace, if any) - // there is no way to preserve the order of waiting threads if several threads - // are waiting to put a trace: the waken up thread is not necessarily the - // first thread to wait. + // there is no way to preserve the order of waiting threads if several + // threads are waiting to put a trace: the waken up thread is not + // necessarily the first thread to wait. ret = sem_post(&_freeBufferSemaphore); @@ -164,13 +168,15 @@ unsigned long LocalTraceBufferPool::toCollect() LocalTraceBufferPool::LocalTraceBufferPool() { - cout << "LocalTraceBufferPool::LocalTraceBufferPool()" << endl; + //cout << "LocalTraceBufferPool::LocalTraceBufferPool()" << endl; _insertPos = ULONG_MAX; // first increment will give 0 _retrievePos = ULONG_MAX; _position=0; // first message will have number = 1 memset(_myBuffer, 0, sizeof(_myBuffer)); // to guarantee end of strings = 0 + for (int i=0; i +#include #include +#include +#include + +using namespace std; #include "LocalTraceCollector.hxx" +#include "LocalTrace_WaitForServerReadiness.hxx" +//#include "SALOME_Log.hxx" +#include +#include CORBA_CLIENT_HEADER(Logger) -using namespace std; +// Class attributes initialisation, for class method LocalTraceCollector::run 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 +pthread_t LocalTraceCollector::_threadId = 0; // used to control single run +int LocalTraceCollector::_toFile = 0; +std::string LocalTraceCollector::_fileName = ""; +CORBA::ORB_ptr LocalTraceCollector::_orb = 0; // ============================================================================ /*! * guarantees a unique object instance of the class (singleton thread safe) * a separate thread for loop to print traces is launched. + * \param typeTrace 0=standard out, 1=file(/tmp/tracetest.log), 2=CORBA log + * If typeTrace=0, checks environment for "SALOME_trace". Test values in + * the following order: + * - "local" standard out + * - "with_logger" CORBA log + * - anything else is kept as a file name */ // ============================================================================ -LocalTraceCollector* LocalTraceCollector::instance() +LocalTraceCollector* LocalTraceCollector::instance(CORBA::ORB_ptr theOrb, + int typeTrace) { if (_singleton == 0) // no need of lock when singleton already exists { @@ -52,10 +70,33 @@ LocalTraceCollector* LocalTraceCollector::instance() 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(); + _singleton = new LocalTraceCollector(); + + _fileName = "/tmp/tracetest.log"; + _toFile=0; + _orb = theOrb; + if (typeTrace) // caller sets a value different from default=0 + _toFile = typeTrace; + else // check environment + { + char* traceKind = getenv("SALOME_trace"); + //cout<<"SALOME_trace="<putMessage(LogMsg); + //cout << " Logger server found" << endl; } + break; + case 0 : ; // --- trace to standard output + default : // --- on standard output, too + break; } // Loop until there is no more buffer to print, @@ -103,27 +185,63 @@ void* LocalTraceCollector::run(void *bid) int fullBuf = myTraceBuffer->retrieve(myTrace); if (myTrace.traceType == ABORT_MESS) { - cout << flush ; - cerr << "INTERRUPTION from thread " << myTrace.threadId - << " : " << myTrace.trace; - cerr << flush ; - exit(1); + switch (_toFile) + { + case 2 : // --- trace collection via CORBA + { + stringstream abortMessage(""); + abortMessage << "INTERRUPTION from thread " + << myTrace.threadId << " : " << myTrace.trace; + CORBA::String_var LogMsg = + CORBA::string_dup(abortMessage.str().c_str()); + m_pInterfaceLogger->putMessage(LogMsg); + exit(1); + } + break; + case 1 : // --- trace to file + traceFile << "INTERRUPTION from thread " << myTrace.threadId + << " : " << myTrace.trace; + traceFile.close(); + // no break here ! + case 0 : // --- trace to standard output + default : // --- on standard output, too + cout << flush ; + cerr << "INTERRUPTION from thread " << myTrace.threadId + << " : " << myTrace.trace; + cerr << flush ; + exit(1); + break; + } } else { - if (_toFile) - traceFile << myTrace.position << " thread " << myTrace.threadId - << " full " << fullBuf <<" " << myTrace.trace; - else - cout << " th. " << myTrace.threadId - << " " << fullBuf <<" " << myTrace.trace; + switch (_toFile) + { + case 2 : // --- trace collection via CORBA + { + stringstream aMessage(""); + aMessage << "th. " << myTrace.threadId + << " " << myTrace.trace; + CORBA::String_var LogMsg = + CORBA::string_dup(aMessage.str().c_str()); + m_pInterfaceLogger->putMessage(LogMsg); + } + break; + case 1 : // --- trace to file + traceFile << "th. " << myTrace.threadId + << " " << myTrace.trace; + break; + case 0 : // --- trace to standard output + default : // --- on standard output, too + cout << "th. " << myTrace.threadId << " " << myTrace.trace; + break; + } } } - if (_toFile) traceFile.close(); + if (_toFile==1) traceFile.close(); } pthread_exit(NULL); - //return 0; // just for warning } // ============================================================================ @@ -147,17 +265,14 @@ LocalTraceCollector:: ~LocalTraceCollector() // ============================================================================ /*! - * Constructor: need of LocalTraceBufferPool object initialization here, - * before creation of thread that access LocalTraceBufferPool: if done after, - * simutaneous call to LocalTraceBufferPool::instance() from different - * threads may lead to multiple instances (instance method not mutex protected) + * Constructor: no need of LocalTraceBufferPool object initialization here, + * thread safe singleton used in LocalTraceBufferPool::instance() */ // ============================================================================ LocalTraceCollector::LocalTraceCollector() { _threadId=0; - LocalTraceBufferPool *myTraceBuffer = LocalTraceBufferPool::instance(); } diff --git a/src/SALOMELocalTrace/LocalTraceCollector.hxx b/src/SALOMELocalTrace/LocalTraceCollector.hxx index 0b0e56ff5..90101efd3 100644 --- a/src/SALOMELocalTrace/LocalTraceCollector.hxx +++ b/src/SALOMELocalTrace/LocalTraceCollector.hxx @@ -27,24 +27,28 @@ #ifndef _LOCALTRACECOLLECTOR_HXX_ #define _LOCALTRACECOLLECTOR_HXX_ +#include +#include #include "LocalTraceBufferPool.hxx" class LocalTraceCollector { public: - static LocalTraceCollector* instance(); + static LocalTraceCollector* instance(CORBA::ORB_ptr theOrb, int typeTrace=0); static void *run(void *bid); ~LocalTraceCollector(); - static int _threadToClose; - static int _toFile; protected: LocalTraceCollector(); private: + static int _threadToClose; + static int _toFile; static LocalTraceCollector* _singleton; static pthread_mutex_t _singletonMutex; static pthread_t _threadId; + static std::string _fileName; + static CORBA::ORB_ptr _orb; }; #endif diff --git a/src/SALOMELocalTrace/LocalTrace_WaitForServerReadiness.cxx b/src/SALOMELocalTrace/LocalTrace_WaitForServerReadiness.cxx new file mode 100644 index 000000000..75a09525a --- /dev/null +++ b/src/SALOMELocalTrace/LocalTrace_WaitForServerReadiness.cxx @@ -0,0 +1,131 @@ +// Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : LocalTrace_WaitForServerReadiness.cxx +// Author : Paul RASCLE (EDF) +// Module : KERNEL +// $Header$ + +#include "LocalTrace_WaitForServerReadiness.hxx" +#include +#include + +using namespace std; + +// ============================================================================ +/*! + * Wait until a server is registered in naming service. + * \param serverName name of the server to find. + * When SALOME_NamingService is available, + * use NamingService_WaitForServerReadiness instead. + * This function is needed when macro MESSAGE used by SALOME_NamingService + * is not available (inside LocalTrace methods, for instance !). + * Direct access to CORBA Name Service. Look for serverName at Name service + * Root without extensions. + */ +// ============================================================================ + +CORBA::Object_ptr LocalTrace_WaitForServerReadiness(CORBA::ORB_ptr orb, + string serverName) +{ + long TIMESleep = 250000000; + int NumberOfTries = 40; + + timespec ts_req; + ts_req.tv_nsec=TIMESleep; + ts_req.tv_sec=0; + timespec ts_rem; + ts_rem.tv_nsec=0; + ts_rem.tv_sec=0; + + CORBA::Object_var obj; + + try + { + // NB. You can't use SALOME_NamingService class because + // it uses MESSAGE macro + // Otherwise, you will get segmentation fault. + + CosNaming::NamingContext_var inc; + CosNaming::Name name; + name.length(1); + name[0].id = CORBA::string_dup(serverName.c_str()); + CORBA::Object_var theObj; + + for (int itry=0; itry < NumberOfTries; itry++) + { + try + { + if(!CORBA::is_nil(orb)) + theObj = orb->resolve_initial_references("NameService"); + if (!CORBA::is_nil(theObj)) + inc = CosNaming::NamingContext::_narrow(theObj); + } + catch( CORBA::COMM_FAILURE& ) + { + cout << "LocalTrace_WaitForServerReadiness: " + << "CORBA::COMM_FAILURE: " + << "Unable to contact the Naming Service" << endl; + } + catch(...) + { + cout << "LocalTrace_WaitForServerReadiness: " + << "Unknown exception dealing with Naming Service" << endl; + } + + if(!CORBA::is_nil(inc)) + { + obj = inc->resolve(name); + if (!CORBA::is_nil(obj)) + { + cout << "LocalTrace_WaitForServerReadiness: " + << serverName << " found in CORBA Name Service" << endl; + break; + } + } + int a = nanosleep(&ts_req,&ts_rem); + cout << "LocalTrace_WaitForServerReadiness: retry look for" + << serverName << endl; + } + } + catch (const CosNaming::NamingContext::NotFound&) + { + cout << "Caught exception: Naming Service can't found Logger"; + } + catch (CORBA::COMM_FAILURE&) + { + cout << "Caught CORBA::SystemException CommFailure."; + } + catch (CORBA::SystemException&) + { + cout << "Caught CORBA::SystemException."; + } + catch (CORBA::Exception&) + { + cout << "Caught CORBA::Exception."; + } + catch (...) + { + cout << "Caught unknown exception."; + } + return obj._retn(); +} + diff --git a/src/SALOMELocalTrace/SALOME_Log.cxx b/src/SALOMELocalTrace/LocalTrace_WaitForServerReadiness.hxx similarity index 55% rename from src/SALOMELocalTrace/SALOME_Log.cxx rename to src/SALOMELocalTrace/LocalTrace_WaitForServerReadiness.hxx index c7059d855..a5e1c9a89 100644 --- a/src/SALOMELocalTrace/SALOME_Log.cxx +++ b/src/SALOMELocalTrace/LocalTrace_WaitForServerReadiness.hxx @@ -1,6 +1,4 @@ -// SALOME_LocalTrace : log on local machine -// -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // // This library is free software; you can redistribute it and/or @@ -21,42 +19,18 @@ // // // -// File : SALOME_Log.hxx -// Author : Vasily Rusyaev, Paul RASCLE, EDF +// File : LocalTrace_WaitForServerReadiness.hxx +// Author : Paul RASCLE (EDF) // Module : KERNEL // $Header$ -#include -#include - -#include "SALOME_Log.hxx" -using namespace std; - -SALOME_Log* SALOME_Log::_singleton = 0; - -// log line size: if too short, log line is truncated, without crash... -char SALOME_LogStr[1024]; +#ifndef _LOCALTRACE_WAITFORSERVERREADINESS_HXX_ +#define _LOCALTRACE_WAITFORSERVERREADINESS_HXX_ -SALOME_Log::SALOME_Log(): ostrstream(SALOME_LogStr,sizeof(SALOME_LogStr)) -{ -} - -SALOME_Log::~SALOME_Log() -{ -} - -SALOME_Log* SALOME_Log::Instance() -{ - if (_singleton == 0) _singleton = new SALOME_Log(); - return _singleton; -} - -void SALOME_Log::putMessage(std::ostream& msg) -{ - cout << std::flush; - cerr <freeze(false); - seekp(0); -} +#include +#include +CORBA::Object_ptr LocalTrace_WaitForServerReadiness(CORBA::ORB_ptr theOrb, + std::string serverName); +#endif diff --git a/src/SALOMELocalTrace/Makefile.in b/src/SALOMELocalTrace/Makefile.in index 8d2beb1d5..5928c6409 100644 --- a/src/SALOMELocalTrace/Makefile.in +++ b/src/SALOMELocalTrace/Makefile.in @@ -37,7 +37,8 @@ VPATH=.:@srcdir@:@top_srcdir@/idl # header files EXPORT_HEADERS= utilities.h \ LocalTraceBufferPool.hxx \ - LocalTraceCollector.hxx + LocalTraceCollector.hxx \ + LocalTrace_WaitForServerReadiness.hxx EXPORT_PYSCRIPTS = @@ -45,8 +46,10 @@ EXPORT_PYSCRIPTS = LIB = libSALOMELocalTrace.la LIB_SRC = LocalTraceCollector.cxx \ - LocalTraceBufferPool.cxx + LocalTraceBufferPool.cxx \ + LocalTrace_WaitForServerReadiness.cxx +LIB_CLIENT_IDL = Logger.idl LDFLAGS+= @CONCLUDE@ diff --git a/src/SALOMELocalTrace/SALOME_Log.hxx b/src/SALOMELocalTrace/SALOME_Log.hxx deleted file mode 100644 index 30694062b..000000000 --- a/src/SALOMELocalTrace/SALOME_Log.hxx +++ /dev/null @@ -1,85 +0,0 @@ -// SALOME Utils : general SALOME's definitions and tools -// -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org -// -// -// -// File : SALOME_Log.hxx -// Author : Vasily Rusyaev (OCN), Paul RASCLE (EDF) -// Module : KERNEL -// $Header$ - -#ifndef _SALOME_LOG_HXX_ -#define _SALOME_LOG_HXX_ - -//these declarations for files don't using OCC includes (for example HDF) -# ifdef WNT - -# ifndef Standard_EXPORT -# define Standard_EXPORT __declspec( dllexport ) -// For global variables : -# define Standard_EXPORTEXTERN __declspec( dllexport ) extern -# define Standard_EXPORTEXTERNC extern "C" __declspec( dllexport ) -# endif /* Standard_EXPORT */ - -# ifndef Standard_IMPORT -# define Standard_IMPORT __declspec( dllimport ) extern -# define Standard_IMPORTC extern "C" __declspec( dllimport ) -# endif /* Standard_IMPORT */ - -# else /* WNT */ - -# ifndef Standard_EXPORT -# define Standard_EXPORT -// For global variables : -# define Standard_EXPORTEXTERN extern -# define Standard_EXPORTEXTERNC extern "C" -# endif /* Standard_EXPORT */ - -# ifndef Standard_IMPORT -# define Standard_IMPORT extern -# define Standard_IMPORTC extern "C" -# endif /* Standard_IMPORT */ - -# endif /* WNT */ - - - -#include -#include - -using namespace std; - -class SALOME_Log : public ostrstream -{ -private: - static SALOME_Log* _singleton; -protected: - //disable creation of instances: force use static SALOME_Log& Instance() - SALOME_Log(); -public: - virtual ~SALOME_Log(); - static Standard_EXPORT SALOME_Log* Instance(); - Standard_EXPORT void putMessage(std::ostream& msg); -}; - -#define SLog SALOME_Log::Instance() - -#endif -- 2.39.2