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