Salome HOME
CCAR: solve some problems during shutdown
[modules/kernel.git] / src / Utils / Utils_DESTRUCTEUR_GENERIQUE.cxx
1 //  SALOME Utils : general SALOME's definitions and tools
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
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. 
10 // 
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. 
15 // 
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 
19 // 
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 //
24 //  File   : Utils_DESTRUCTEUR_GENERIQUE.cxx
25 //  Author : Antoine YESSAYAN, EDF
26 //  Module : SALOME
27 //  $Header$
28
29
30 # include <iostream>
31 # include <list>
32 extern "C"
33 {
34 # include <stdlib.h>
35 }
36
37 # include "Utils_DESTRUCTEUR_GENERIQUE.hxx"
38 //# include "utilities.h"
39 # include "LocalTraceBufferPool.hxx"
40 void Nettoyage();
41
42 #ifdef _DEBUG_
43 static int MYDEBUG = 0;
44 #else
45 static int MYDEBUG = 0;
46 #endif
47
48 using namespace std;
49
50 std::list<DESTRUCTEUR_GENERIQUE_*> *DESTRUCTEUR_GENERIQUE_::Destructeurs=0 ;
51
52 /*! \class ATEXIT_
53  *
54  * Mecanisme pour faire executer une seule fois DESTRUCTEUR_GENERIQUE_::Nettoyage
55  * a la fin du traitement : creation d'un singleton statique de l'objet
56  * tres specialise ATEXIT_.
57  *
58  * La creation d'un objet de type ATEXIT_ entraine l'inscription de la fonction
59  * Nettoyage() par atexit(). Il suffit donc de creer un singleton statique du type ATEXIT_
60  * pour effectuer cet enregistrement une seule fois independament de l'utilisateur.
61  */
62
63 //CCRT
64 static bool ATEXIT_Done = false ;
65 //CCRT
66
67 class ATEXIT_
68 {
69 public :
70         /*!
71          * Allocation dynamique de Destructeurs, une liste chainee de DESTRUCTEUR_GENERIQUE_* et enregistrement
72          * de la fonction Nettoyage() par atexit().
73          *
74          * La liste chainee Destructeurs est detruite dans la fonction Nettoyage.
75          */
76         //CCRT  ATEXIT_( void )
77         ATEXIT_( bool Make_ATEXIT )
78         {
79           //CCRT
80           if ( Make_ATEXIT && !ATEXIT_Done ) {
81             //CCRT
82                 assert (DESTRUCTEUR_GENERIQUE_::Destructeurs==0);
83                 //cerr << "ATEXIT_::ATEXIT_ Construction ATEXIT" << endl;// message necessaire pour utiliser logger dans Nettoyage (cf.BUG KERNEL4561)
84                 DESTRUCTEUR_GENERIQUE_::Destructeurs = 
85                       new std::list<DESTRUCTEUR_GENERIQUE_*> ; // Destructeur alloue dynamiquement (cf. ci-dessous) ,
86                                                                    // il est utilise puis detruit par la fonction Nettoyage
87                 //To be sure the trace singleton will be the last one to be destroyed initialize it here before calling atexit
88                 LocalTraceBufferPool::instance();
89                 int cr = atexit( Nettoyage );                      // execute Nettoyage lors de exit, aprs la destruction des donnees statiques !
90                 assert(cr==0) ;
91                 ATEXIT_Done = true ;
92           }
93         }
94
95         ~ATEXIT_( )
96         {
97           //cerr << "ATEXIT_::~ATEXIT_ Destruction ATEXIT" << endl;
98         }
99 };
100
101
102
103
104 static ATEXIT_ nettoyage = ATEXIT_( false );    /* singleton statique */
105
106
107 /*!
108  * traitement effectue :
109  * -# execution de tous les objets de type DESTRUCTEUR_DE_ stockes dans la liste Destructeurs (ce qui detruit les
110  *    singletons correspondant) ;
111  * -# puis destruction de tous les objets de type DESTRUCTEUR_DE_ stockes dans la liste Destructeurs;
112  * -# destruction de la liste Destructeurs.
113  */
114
115 void Nettoyage( void )
116 {
117   //cerr << "Nettoyage()" << endl;
118   //if(MYDEBUG) BEGIN_OF("Nettoyage( void )") ;
119         assert(DESTRUCTEUR_GENERIQUE_::Destructeurs) ;
120         //if(MYDEBUG) SCRUTE( DESTRUCTEUR_GENERIQUE_::Destructeurs->size() ) ;
121         if( DESTRUCTEUR_GENERIQUE_::Destructeurs->size() )
122         {
123                 std::list<DESTRUCTEUR_GENERIQUE_*>::iterator it = DESTRUCTEUR_GENERIQUE_::Destructeurs->end() ;
124
125                 do
126                 {
127                   //if(MYDEBUG) MESSAGE( "DESTRUCTION d'un SINGLETON");
128                         it-- ;
129                         DESTRUCTEUR_GENERIQUE_* ptr = *it ;
130                         //DESTRUCTEUR_GENERIQUE_::Destructeurs->remove( *it ) ;
131                         (*ptr)() ;
132                         delete ptr ;
133                 }while( it!=  DESTRUCTEUR_GENERIQUE_::Destructeurs->begin() ) ;
134
135                 DESTRUCTEUR_GENERIQUE_::Destructeurs->clear() ;
136                 //if(MYDEBUG) SCRUTE( DESTRUCTEUR_GENERIQUE_::Destructeurs->size() ) ;
137                 assert( DESTRUCTEUR_GENERIQUE_::Destructeurs->size()==0 ) ;
138                 assert( DESTRUCTEUR_GENERIQUE_::Destructeurs->empty() ) ;
139         }
140
141         delete DESTRUCTEUR_GENERIQUE_::Destructeurs;
142         DESTRUCTEUR_GENERIQUE_::Destructeurs=0;
143         //if(MYDEBUG) END_OF("Nettoyage( void )") ;
144         return ;
145 }
146
147
148 /*!
149  * Adds a destruction object to the list of actions to be performed at the end
150  * of the process
151  */
152 const int DESTRUCTEUR_GENERIQUE_::Ajout( DESTRUCTEUR_GENERIQUE_ &objet )
153 {
154         // N.B. : l'ordre de creation des SINGLETON etant important
155         //        on n'utilise pas deux fois la meme position pour
156         //        les stocker dans la pile des objets.
157
158         //CCRT
159         if ( !ATEXIT_Done ) {
160           nettoyage = ATEXIT_( true ) ;
161         }
162         //CCRT
163         assert(Destructeurs) ;
164         Destructeurs->push_back( &objet ) ;
165         return Destructeurs->size() ;
166 }