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