Back to index

salome-kernel  6.5.0
BasicsGenericDestructor.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 //  SALOME Basics : general SALOME definitions and tools (C++ part - no CORBA)
00024 //  File   : BasicGenericDestructor.cxx
00025 //  Author : Antoine YESSAYAN, Paul RASCLE, EDF
00026 //  Module : SALOME
00027 //  $Header: /home/server/cvs/KERNEL/KERNEL_SRC/src/Basics/BasicsGenericDestructor.cxx,v 1.6.2.1.10.3.12.1 2012-04-12 14:05:02 vsr Exp $
00028 //
00029 #include <iostream>
00030 #include <list>
00031 #include <cstdlib>
00032 
00033 #include "BasicsGenericDestructor.hxx"
00034 
00035 void HouseKeeping();
00036 
00037 std::list<PROTECTED_DELETE*> PROTECTED_DELETE::_objList;
00038 #ifndef WIN32
00039 pthread_mutex_t PROTECTED_DELETE::_listMutex;
00040 #else
00041 pthread_mutex_t PROTECTED_DELETE::_listMutex =
00042   PTHREAD_MUTEX_INITIALIZER;
00043 #endif
00044 
00045 std::list<GENERIC_DESTRUCTOR*> *GENERIC_DESTRUCTOR::Destructors = 0;
00046 static bool atExitSingletonDone = false ;
00047 
00048 // ============================================================================
00054 // ============================================================================
00055 
00056 void PROTECTED_DELETE::deleteInstance(PROTECTED_DELETE *anObject)
00057   {
00058     if (std::find(_objList.begin(), _objList.end(),anObject) == _objList.end())
00059       return;
00060     else
00061       {
00062         int ret;
00063         ret = pthread_mutex_lock(&_listMutex); // acquire lock, an check again
00064         if (std::find(_objList.begin(), _objList.end(), anObject)
00065             != _objList.end())
00066           {
00067             DEVTRACE("PROTECTED_DELETE::deleteInstance1 " << anObject);
00068             delete anObject;
00069             DEVTRACE("PROTECTED_DELETE::deleteInstance2 " << &_objList);
00070             _objList.remove(anObject);
00071           }
00072         ret = pthread_mutex_unlock(&_listMutex); // release lock
00073       }
00074   }
00075 
00076 // ============================================================================
00081 // ============================================================================
00082 
00083 void PROTECTED_DELETE::addObj(PROTECTED_DELETE *anObject)
00084 {
00085   DEVTRACE("PROTECTED_DELETE::addObj " << anObject);
00086   _objList.push_back(anObject);
00087 }
00088 
00089 // ============================================================================
00093 // ============================================================================
00094 
00095 PROTECTED_DELETE::~PROTECTED_DELETE()
00096 {
00097   DEVTRACE("PROTECTED_DELETE::~PROTECTED_DELETE()");
00098 }
00099 
00100 // ============================================================================
00109 // ============================================================================
00110 
00111 class atExitSingleton
00112 {
00113 public:
00114   atExitSingleton(bool Make_ATEXIT)
00115   {
00116     if (Make_ATEXIT && !atExitSingletonDone)
00117       {
00118         DEVTRACE("atExitSingleton(" << Make_ATEXIT << ")");
00119         assert(GENERIC_DESTRUCTOR::Destructors == 0);
00120         GENERIC_DESTRUCTOR::Destructors = new std::list<GENERIC_DESTRUCTOR*>;
00121 #ifndef _DEBUG_
00122         atexit(HouseKeeping);
00123 #else
00124         int cr = atexit(HouseKeeping);
00125         assert(cr == 0);
00126 #endif
00127         atExitSingletonDone = true;
00128       }
00129   }
00130 
00131   ~atExitSingleton()
00132   {
00133     DEVTRACE("atExitSingleton::~atExitSingleton()");
00134   }
00135 };
00136 
00138 
00139 static atExitSingleton HouseKeeper = atExitSingleton(false);
00140 
00141 // ============================================================================
00147 // ============================================================================
00148 
00149 void HouseKeeping( void )
00150 {
00151   DEVTRACE("HouseKeeping()");
00152   assert(GENERIC_DESTRUCTOR::Destructors);
00153   if(GENERIC_DESTRUCTOR::Destructors->size())
00154     {
00155       std::list<GENERIC_DESTRUCTOR*>::iterator it =
00156         GENERIC_DESTRUCTOR::Destructors->end();
00157 
00158       do
00159         {
00160           it-- ;
00161           GENERIC_DESTRUCTOR* ptr = *it ;
00162           DEVTRACE("HouseKeeping() " << typeid(ptr).name());
00163           (*ptr)();
00164           delete ptr ;
00165         }
00166       while (it !=  GENERIC_DESTRUCTOR::Destructors->begin()) ;
00167 
00168       DEVTRACE("HouseKeeping() end list ");
00169       GENERIC_DESTRUCTOR::Destructors->clear() ;
00170       assert(GENERIC_DESTRUCTOR::Destructors->size() == 0);
00171       assert(GENERIC_DESTRUCTOR::Destructors->empty());
00172       DEVTRACE("HouseKeeping()after clear ");
00173     }
00174 
00175   delete GENERIC_DESTRUCTOR::Destructors;
00176   GENERIC_DESTRUCTOR::Destructors = 0;
00177   atExitSingletonDone = false ;
00178   DEVTRACE("HouseKeeping() very end ");
00179   return ;
00180 }
00181 
00182 // ============================================================================
00187 // ============================================================================
00188 
00189 const int GENERIC_DESTRUCTOR::Add(GENERIC_DESTRUCTOR &anObject)
00190 {
00191   DEVTRACE("GENERIC_DESTRUCTOR::Add("<<typeid(anObject).name()<<") "
00192            << &anObject);
00193   if (!atExitSingletonDone)
00194     {
00195       HouseKeeper = atExitSingleton(true);
00196     }
00197   assert(Destructors);
00198   Destructors->push_back(&anObject);
00199   return Destructors->size();
00200 }