1 // Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SALOME Basics : general SALOME definitions and tools (C++ part - no CORBA)
24 // File : BasicGenericDestructor.cxx
25 // Author : Antoine YESSAYAN, Paul RASCLE, EDF
33 #include "BasicsGenericDestructor.hxx"
37 std::list<PROTECTED_DELETE*> PROTECTED_DELETE::_objList;
39 pthread_mutex_t PROTECTED_DELETE::_listMutex;
41 pthread_mutex_t PROTECTED_DELETE::_listMutex =
42 PTHREAD_MUTEX_INITIALIZER;
45 std::list<GENERIC_DESTRUCTOR*> *GENERIC_DESTRUCTOR::Destructors = 0;
46 static bool atExitSingletonDone = false ;
48 // ============================================================================
50 * deleteInstance deletes only once the object. Only object present on the
51 * static list of PROTECTED_DELETE* are deleted, then removed of the list.
52 * The operation is protected by a mutex.
54 // ============================================================================
56 void PROTECTED_DELETE::deleteInstance(PROTECTED_DELETE *anObject)
58 if (std::find(_objList.begin(), _objList.end(),anObject) == _objList.end())
63 ret = pthread_mutex_lock(&_listMutex); // acquire lock, an check again
64 if (std::find(_objList.begin(), _objList.end(), anObject)
67 DEVTRACE("PROTECTED_DELETE::deleteInstance1 " << anObject);
69 DEVTRACE("PROTECTED_DELETE::deleteInstance2 " << &_objList);
70 _objList.remove(anObject);
72 ret = pthread_mutex_unlock(&_listMutex); // release lock
76 // ============================================================================
78 * To allow a further destruction of a PRTECTED_DELETE object, it must be added
79 * to the static list of PROTECTED_DELETE*
81 // ============================================================================
83 void PROTECTED_DELETE::addObj(PROTECTED_DELETE *anObject)
85 DEVTRACE("PROTECTED_DELETE::addObj " << anObject);
86 _objList.push_back(anObject);
89 // ============================================================================
91 * Herited classes have there own destructors
93 // ============================================================================
95 PROTECTED_DELETE::~PROTECTED_DELETE()
97 DEVTRACE("PROTECTED_DELETE::~PROTECTED_DELETE()");
100 // ============================================================================
102 * To execute only once GENERIC_DESTRUCTOR::HouseKeeping et the end of process,
103 * a dedicated object is created, as a singleton: atExitSingleton.
104 * When the singleton is created, the HouseKeeping() function is registered in
106 * Destructors is a list created on heap, and deleted by HouseKeeping(), with
109 // ============================================================================
111 class atExitSingleton
114 atExitSingleton(bool Make_ATEXIT)
116 if (Make_ATEXIT && !atExitSingletonDone)
118 DEVTRACE("atExitSingleton(" << Make_ATEXIT << ")");
119 assert(GENERIC_DESTRUCTOR::Destructors == 0);
120 GENERIC_DESTRUCTOR::Destructors = new std::list<GENERIC_DESTRUCTOR*>;
122 atexit(HouseKeeping);
124 int cr = atexit(HouseKeeping);
127 atExitSingletonDone = true;
133 DEVTRACE("atExitSingleton::~atExitSingleton()");
137 //! static singleton for atExitSingleton class
139 static atExitSingleton HouseKeeper = atExitSingleton(false);
141 // ============================================================================
143 * Executes all objects of type DESTRUCTOR_OF in the Destructors list.
144 * Deletes all objects of type DESTRUCTOR_OF in the Destructors list.
147 // ============================================================================
149 void HouseKeeping( void )
151 DEVTRACE("HouseKeeping()");
152 assert(GENERIC_DESTRUCTOR::Destructors);
153 if(GENERIC_DESTRUCTOR::Destructors->size())
155 std::list<GENERIC_DESTRUCTOR*>::iterator it =
156 GENERIC_DESTRUCTOR::Destructors->end();
161 GENERIC_DESTRUCTOR* ptr = *it ;
162 DEVTRACE("HouseKeeping() " << typeid(ptr).name());
166 while (it != GENERIC_DESTRUCTOR::Destructors->begin()) ;
168 DEVTRACE("HouseKeeping() end list ");
169 GENERIC_DESTRUCTOR::Destructors->clear() ;
170 assert(GENERIC_DESTRUCTOR::Destructors->size() == 0);
171 assert(GENERIC_DESTRUCTOR::Destructors->empty());
172 DEVTRACE("HouseKeeping()after clear ");
175 delete GENERIC_DESTRUCTOR::Destructors;
176 GENERIC_DESTRUCTOR::Destructors = 0;
177 atExitSingletonDone = false ;
178 DEVTRACE("HouseKeeping() very end ");
182 // ============================================================================
184 * Adds a destruction object to the list of actions to be performed at the end
187 // ============================================================================
189 const int GENERIC_DESTRUCTOR::Add(GENERIC_DESTRUCTOR &anObject)
191 DEVTRACE("GENERIC_DESTRUCTOR::Add("<<typeid(anObject).name()<<") "
193 if (!atExitSingletonDone)
195 HouseKeeper = atExitSingleton(true);
198 Destructors->push_back(&anObject);
199 return (int)Destructors->size();