std::list<GENERIC_DESTRUCTOR*> *GENERIC_DESTRUCTOR::Destructors = 0;
static bool atExitSingletonDone = false ;
+// ============================================================================
+/*!
+ * deleteInstance deletes only once the object. Only object present on the
+ * static list of PROTECTED_DELETE* are deleted, then removed of the list.
+ * The operation is protected by a mutex.
+ */
+// ============================================================================
+
void PROTECTED_DELETE::deleteInstance(PROTECTED_DELETE *anObject)
{
if (std::find(_objList.begin(), _objList.end(),anObject) == _objList.end())
if (std::find(_objList.begin(), _objList.end(), anObject)
!= _objList.end())
{
- cerr << "PROTECTED_DELETE::deleteInstance1 " << anObject << endl;
+ DEVTRACE("PROTECTED_DELETE::deleteInstance1 " << anObject);
delete anObject;
- cerr << "PROTECTED_DELETE::deleteInstance2 " << &_objList << endl;
+ DEVTRACE("PROTECTED_DELETE::deleteInstance2 " << &_objList);
_objList.remove(anObject);
- cerr << "PROTECTED_DELETE::deleteInstance3" << endl;
}
ret = pthread_mutex_unlock(&_listMutex); // release lock
}
}
+// ============================================================================
+/*!
+ * To allow a further destruction of a PRTECTED_DELETE object, it must be added
+ * to the static list of PROTECTED_DELETE*
+ */
+// ============================================================================
+
void PROTECTED_DELETE::addObj(PROTECTED_DELETE *anObject)
{
- cerr << "PROTECTED_DELETE::addObj " << anObject << endl;
+ DEVTRACE("PROTECTED_DELETE::addObj " << anObject);
_objList.push_back(anObject);
}
+// ============================================================================
+/*!
+ * Herited classes have there own destructors
+ */
+// ============================================================================
+
PROTECTED_DELETE::~PROTECTED_DELETE()
{
- cerr << "PROTECTED_DELETE::~PROTECTED_DELETE()" << endl;
+ DEVTRACE("PROTECTED_DELETE::~PROTECTED_DELETE()");
}
// ============================================================================
{
if (Make_ATEXIT && !atExitSingletonDone)
{
- cerr << "atExitSingleton(" << Make_ATEXIT << ")" << endl;
+ DEVTRACE("atExitSingleton(" << Make_ATEXIT << ")");
assert(GENERIC_DESTRUCTOR::Destructors == 0);
GENERIC_DESTRUCTOR::Destructors = new std::list<GENERIC_DESTRUCTOR*>;
int cr = atexit(HouseKeeping);
~atExitSingleton()
{
- cerr << "atExitSingleton::~atExitSingleton()" << endl << flush;
+ DEVTRACE("atExitSingleton::~atExitSingleton()");
}
};
void HouseKeeping( void )
{
- cerr << "HouseKeeping()" << endl;
+ DEVTRACE("HouseKeeping()");
assert(GENERIC_DESTRUCTOR::Destructors);
if(GENERIC_DESTRUCTOR::Destructors->size())
{
{
it-- ;
GENERIC_DESTRUCTOR* ptr = *it ;
- cerr << "HouseKeeping() " << typeid(ptr).name() << endl;
+ DEVTRACE("HouseKeeping() " << typeid(ptr).name());
(*ptr)();
delete ptr ;
}
while (it != GENERIC_DESTRUCTOR::Destructors->begin()) ;
- cerr << "HouseKeeping() end list "<< endl;
+ DEVTRACE("HouseKeeping() end list ");
GENERIC_DESTRUCTOR::Destructors->clear() ;
assert(GENERIC_DESTRUCTOR::Destructors->size() == 0);
assert(GENERIC_DESTRUCTOR::Destructors->empty());
- cerr << "HouseKeeping()after clear "<< endl;
+ DEVTRACE("HouseKeeping()after clear ");
}
delete GENERIC_DESTRUCTOR::Destructors;
GENERIC_DESTRUCTOR::Destructors = 0;
- cerr << "HouseKeeping() very end "<< endl;
+ DEVTRACE("HouseKeeping() very end ");
return ;
}
const int GENERIC_DESTRUCTOR::Add(GENERIC_DESTRUCTOR &anObject)
{
- cerr << "GENERIC_DESTRUCTOR::Add("<<typeid(anObject).name()<<") "
- << &anObject << endl;
+ DEVTRACE("GENERIC_DESTRUCTOR::Add("<<typeid(anObject).name()<<") "
+ << &anObject);
if (!atExitSingletonDone)
{
HouseKeeper = atExitSingleton(true);
}
assert(Destructors);
-// if (std::find(Destructors->begin(), Destructors->end(), &anObject)
-// == Destructors->end())
-// {
-// Destructors->push_back(&anObject);
-// }
Destructors->push_back(&anObject);
return Destructors->size();
}
#include <algorithm>
#include <cassert>
#include <typeinfo>
+#include <iostream>
+#include <cstdlib>
#include <pthread.h>
#if defined BASICS_EXPORTS
#endif
#endif
+//#define _DEVDEBUG_
+
+#ifdef _DEVDEBUG_
+#define MYDEVTRACE {std::cerr << __FILE__ << " [" << __LINE__ << "] : ";}
+#define DEVTRACE(msg) {MYDEVTRACE; std::cerr<<msg<<std::endl<<std::flush;}
+#else
+#define MYDEVTRACE
+#define DEVTRACE(msg)
+#endif
+
+// ============================================================================
+/*!
+ * The PROTECTED_DELETE base class provides a protected destructor.
+ * The only way to use PROTECTED_DELETE is inheritance:
+ * example: class LocalTraceBufferPool : public PROTECTED_DELETE
+ * Herited class destructor must stay protected.
+ * Normal use is:
+ * - create an instance of herited class on the heap (new),
+ * - use addObj(instance) to store the instance on the static list _objList,
+ * - delete instance with deleteInstance(instance)
+ *
+ * This class is utilised with GENERIC_DESTRUCTOR and DESTRUCTOR_OF,
+ * to program automatic deletion of objects at the end of the process, while
+ * keeping the possibility of an early destruction, if required. This is used
+ * for unit testing and trace mecanism.
+ */
+// ============================================================================
+
class PROTECTED_DELETE
{
public:
DESTRUCTOR_OF(TYPE &anObject):
_objectPtr(&anObject)
{
- std::cerr << " DESTRUCTOR_OF " << typeid(anObject).name()
- << " " << _objectPtr << " " << this << endl;
+ DEVTRACE(" DESTRUCTOR_OF " << typeid(anObject).name()
+ << " " << _objectPtr << " " << this );
PROTECTED_DELETE::addObj(_objectPtr);
assert(GENERIC_DESTRUCTOR::Add(*this) >= 0);
}
{
if (_objectPtr)
{
- //TYPE* aPtr = static_cast<TYPE*>(_objectPtr);
- //std::cerr << "DESTRUCTOR_OF<" << typeid(*aPtr).name()
- // << ">::operator() " << _objectPtr << " " << aPtr << endl;
- //if (aPtr) PROTECTED_DELETE::deleteInstance(_objectPtr);
- std::cerr << "DESTRUCTOR_OF<>::operator() " << _objectPtr << endl;
+ DEVTRACE("DESTRUCTOR_OF<>::operator() " << _objectPtr);
if (_objectPtr) PROTECTED_DELETE::deleteInstance(_objectPtr);
_objectPtr = NULL;
}
virtual ~DESTRUCTOR_OF()
{
- cerr << "~DESTRUCTOR_OF() " << this << endl;
+ DEVTRACE("~DESTRUCTOR_OF() " << this);
assert(!_objectPtr);
}
ret = pthread_mutex_lock(&_singletonMutex); // acquire lock to be alone
if (_singleton == 0) // another thread may have got
{ // the lock after the first test
- //cerr << "FileTraceCollector:: instance()" << endl << flush;
+ DEVTRACE("FileTraceCollector:: instance()");
_singleton = new FileTraceCollector();
_fileName = fileName;
- //cerr << " _fileName: " << _fileName << endl;
+ DEVTRACE(" _fileName: " << _fileName);
pthread_t traceThread;
int bid;
int re2 = pthread_create(&traceThread, NULL,
FileTraceCollector::run, (void *)bid);
- //cerr << "FileTraceCollector:: instance()-end" << endl << flush;
+ DEVTRACE("FileTraceCollector:: instance()-end");
}
ret = pthread_mutex_unlock(&_singletonMutex); // release lock
}
while ((!_threadToClose) || myTraceBuffer->toCollect() )
{
if (_threadToClose)
- cerr << "FileTraceCollector _threadToClose" << endl << flush;
+ DEVTRACE("FileTraceCollector _threadToClose");
int fullBuf = myTraceBuffer->retrieve(myTrace);
if (myTrace.traceType == ABORT_MESS)
#endif
}
}
- cerr <<"traceFile.close();" << endl << flush;
+ DEVTRACE("traceFile.close()");
traceFile.close();
- cerr <<"traceFile.close()_end;" << endl << flush;
+ DEVTRACE("traceFile.close()_end");
pthread_exit(NULL);
}
//return NULL;
ret = pthread_mutex_lock(&_singletonMutex); // acquire lock to be alone
if (_singleton)
{
- cerr << "FileTraceCollector:: ~FileTraceCollector()" << endl << flush;
+ DEVTRACE("FileTraceCollector:: ~FileTraceCollector()");
LocalTraceBufferPool* myTraceBuffer = LocalTraceBufferPool::instance();
_threadToClose = 1;
myTraceBuffer->insert(NORMAL_MESS,"end of trace\n"); // to wake up thread
{
int ret = pthread_join(*_threadId, NULL);
if (ret) cerr << "error close FileTraceCollector : "<< ret << endl;
- else cerr << "FileTraceCollector destruction OK" << endl;
+ else DEVTRACE("FileTraceCollector destruction OK");
_threadId = 0;
_threadToClose = 0;
}
int ret = pthread_mutex_lock(&_singletonMutex); // acquire lock to be alone
if (_singleton)
{
- cerr << "LocalTraceBufferPool::~LocalTraceBufferPool()" << endl<<flush;
+ DEVTRACE("LocalTraceBufferPool::~LocalTraceBufferPool()");
delete (_myThreadTrace);
_myThreadTrace = 0;
int ret;
ret=sem_destroy(&_freeBufferSemaphore);
ret=sem_destroy(&_fullBufferSemaphore);
ret=pthread_mutex_destroy(&_incrementMutex);
- cerr<<"LocalTraceBufferPool::~LocalTraceBufferPool()-end"<<endl<<flush;
+ DEVTRACE("LocalTraceBufferPool::~LocalTraceBufferPool()-end");
_singleton = 0;
ret = pthread_mutex_unlock(&_singletonMutex); // release lock
}
CORBA::String_var LogMsg =
CORBA::string_dup("\n---Init logger trace---\n");
m_pInterfaceLogger->putMessage(LogMsg);
- //cerr << " Logger server found" << endl;
+ DEVTRACE("Logger server found");
}
// --- Loop until there is no more buffer to print,
ret = pthread_mutex_lock(&_singletonMutex); // acquire lock to be alone
if (_singleton)
{
- //cerr << "SALOMETraceCollector:: ~SALOMETraceCollector()" <<endl<<flush;
+ DEVTRACE("SALOMETraceCollector:: ~SALOMETraceCollector()");
LocalTraceBufferPool* myTraceBuffer = LocalTraceBufferPool::instance();
_threadToClose = 1;
myTraceBuffer->insert(NORMAL_MESS,"end of trace\n"); // to wake up thread
{
int ret = pthread_join(*_threadId, NULL);
if (ret) cerr << "error close SALOMETraceCollector : "<< ret << endl;
- //else cerr << "SALOMETraceCollector destruction OK" << endl;
+ else DEVTRACE("SALOMETraceCollector destruction OK");
_threadId = 0;
_threadToClose = 0;
}