Salome HOME
NRI : Temporary modification for reading catalog of modules.
[modules/kernel.git] / src / MPIContainer / MPIContainer_i.cxx
1 using namespace std;
2 #include <iostream.h>
3 #include <dlfcn.h>
4 #include <stdio.h>
5 #include "MPIContainer_i.hxx"
6 #include "utilities.h"
7
8 MPIContainer_i::MPIContainer_i(int nbproc, int numproc,
9                                CORBA::ORB_ptr orb, 
10                                PortableServer::POA_ptr poa,
11                                char * containerName) 
12   : Engines_Container_i(orb,poa,containerName,0), MPIObject_i(nbproc,numproc)
13 {
14   _id = _poa->activate_object(this);
15
16   MESSAGE("[" << _numproc << "] containerName=" << _containerName);
17   if( _numproc ==  0 ){
18     _NS = SINGLETON_<SALOME_NamingService>::Instance() ;
19     ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting()) ;
20     _NS->init_orb( orb ) ;
21
22     Engines::Container_ptr pCont 
23       = Engines::Container::_narrow(POA_Engines::MPIContainer::_this());
24     _NS->Register(pCont, _containerName.c_str()); 
25   }
26
27   // Root recupere les ior des container des autre process
28   Engines::MPIObject_var pobj = POA_Engines::MPIContainer::_this();
29   BCastIOR(_orb,pobj,true);
30 }
31
32 MPIContainer_i::~MPIContainer_i(void)
33 {
34   if( !handle_map.empty() ){
35     MESSAGE("[" << _numproc << "] MPIContainer_i::~MPIContainer_i: warning destroy a not empty container");
36   }
37 }
38
39 // Load component
40 Engines::Component_ptr MPIContainer_i::load_impl(const char* nameToRegister,
41                                                  const char* componentName)
42 {
43   int ip;
44   Engines::Component_var iobject;
45   Engines::MPIObject_var pobj;
46   char cproc[4];
47
48   if( _numproc == 0 ){
49     // Invocation du chargement du composant dans les autres process
50     for(ip= 1;ip<_nbproc;ip++)
51       (Engines::MPIContainer::_narrow((*_tior)[ip]))->load_impl(nameToRegister,
52                                                                 componentName);
53   }
54
55   sprintf(cproc,"_%d",_numproc);
56
57   BEGIN_OF("[" << _numproc << "] MPIContainer_i::load_impl");
58
59   _numInstanceMutex.lock() ; // lock on the instance number
60   _numInstance++ ;
61   char _aNumI[12];
62   sprintf(_aNumI,"%d",_numInstance) ;
63   _numInstanceMutex.unlock() ;
64
65   string _impl_name = componentName;
66   string instanceName = string(nameToRegister) + "_inst_" + _aNumI + cproc;
67
68   string absolute_impl_name(_impl_name);
69   MESSAGE("[" << _numproc << "] absolute_impl_name=" << absolute_impl_name);
70   void * handle = dlopen(absolute_impl_name.c_str(), RTLD_LAZY);
71   if(!handle){
72     INFOS("[" << _numproc << "] Can't load shared library : " << absolute_impl_name);
73     INFOS("[" << _numproc << "] error dlopen: " << dlerror());
74     return Engines::Component::_nil() ;
75   }
76
77   string factory_name = string(nameToRegister) + string("Engine_factory");
78   MESSAGE("[" << _numproc << "] factory_name=" << factory_name) ;
79
80   PortableServer::ObjectId * (*MPIComponent_factory) (int,int,
81                                                   CORBA::ORB_ptr,
82                                                   PortableServer::POA_ptr,
83                                                   PortableServer::ObjectId *,
84                                                   const char *,
85                                                   const char *) =
86     (PortableServer::ObjectId * (*) (int,int,
87                                      CORBA::ORB_ptr,
88                                      PortableServer::POA_ptr, 
89                                      PortableServer::ObjectId *, 
90                                      const char *, 
91                                      const char *)) 
92     dlsym(handle, factory_name.c_str());
93
94   char *error ;
95   if ((error = dlerror()) != NULL){
96     // Try to load a sequential component
97     MESSAGE("[" << _numproc << "] Try to load a sequential component");
98     iobject = Engines_Container_i::load_impl(nameToRegister,componentName);
99     if( CORBA::is_nil(iobject) ) return Engines::Component::_duplicate(iobject);
100   }
101   else{
102     // Instanciation du composant parallele
103     MESSAGE("[" << _numproc << "] Try to load a parallel component");
104     PortableServer::ObjectId * id = (MPIComponent_factory)
105       (_nbproc,_numproc,_orb, _poa, _id, instanceName.c_str(), nameToRegister);
106     // get reference from id
107     CORBA::Object_var o = _poa->id_to_reference(*id);
108     pobj = Engines::MPIObject::_narrow(o) ;
109     iobject = Engines::Component::_narrow(pobj) ;
110   }
111
112   // Root recupere les ior des composants des autre process
113   BCastIOR(_orb,pobj,false);
114
115   if( _numproc == 0 ){
116     // utiliser + tard le registry ici :
117     // register the engine under the name containerName.dir/nameToRegister.object
118     string component_registerName = _containerName + "/" + nameToRegister;
119     _NS->Register(iobject, component_registerName.c_str()) ;
120   }
121
122   _numInstanceMutex.lock() ; // lock on the add on handle_map (necessary ?)
123   handle_map[instanceName] = handle;
124   _numInstanceMutex.unlock() ;
125   END_OF("[" <<_numproc << "] MPIContainer_i::load_impl");
126   return Engines::Component::_duplicate(iobject);
127
128 }
129
130 void MPIContainer_i::remove_impl(Engines::Component_ptr component_i)
131 {
132   int ip;
133   Engines::Component_ptr cptr;
134   Engines::MPIObject_ptr pcptr;
135   Engines::MPIObject_ptr spcptr;
136
137   ASSERT(! CORBA::is_nil(component_i));
138
139   if( _numproc == 0 ){
140     // Invocation de la destruction du composant dans les autres process
141     pcptr = (Engines::MPIObject_ptr)component_i;
142     for(ip= 1;ip<_nbproc;ip++){
143       spcptr = Engines::MPIObject::_narrow((*(pcptr->tior()))[ip]);
144       cptr = (Engines::Component_ptr)spcptr;
145       (Engines::MPIContainer::_narrow((*_tior)[ip]))->remove_impl(cptr);
146     }
147   }
148
149   string instanceName = component_i->instanceName() ;
150   MESSAGE("[" << _numproc << "] unload component " << instanceName);
151   component_i->destroy() ;
152   MESSAGE("[" << _numproc << "] test key handle_map");
153   _numInstanceMutex.lock() ; // lock on the remove on handle_map
154   if (handle_map[instanceName]) // if key does not exist, created & initialized null
155     {
156       remove_map[instanceName] = handle_map[instanceName] ;
157     }
158   else MESSAGE("[" << _numproc << "] no key handle_map");
159   handle_map.erase(instanceName) ;   
160   _numInstanceMutex.unlock() ;
161   MESSAGE("[" << _numproc << "] list handle_map");
162   map<string, void *>::iterator im ;
163   for (im = handle_map.begin() ; im != handle_map.end() ; im ++)
164     {
165       MESSAGE("[" << _numproc << "] stay " << (*im).first);
166     }
167 }
168
169 void MPIContainer_i::finalize_removal()
170 {
171   int ip;
172
173   MESSAGE("[" << _numproc << "] finalize unload : dlclose");
174
175   if( _numproc == 0 ){
176     // Invocation de la destruction du composant dans les autres process
177     for(ip= 1;ip<_nbproc;ip++)
178       (Engines::MPIContainer::_narrow((*_tior)[ip]))->finalize_removal();
179   }
180
181   map<string, void *>::iterator im ;
182   _numInstanceMutex.lock() ; // lock on the explore remove_map & dlclose
183   for (im = remove_map.begin() ; im != remove_map.end() ; im ++)
184     {
185       void * handle = (*im).second ;
186       dlclose(handle) ;
187       MESSAGE("[" << _numproc << "] dlclose " << (*im).first);
188     }
189   remove_map.clear() ;  
190   _numInstanceMutex.unlock() ;
191   MESSAGE("[" << _numproc << "] remove_map.clear()");
192 }