1 // SALOME MPIContainer : implemenation of container based on MPI libraries
3 // Copyright (C) 2003 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.
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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : MPIContainer_i.cxx
31 #include "MPIContainer_i.hxx"
32 #include "utilities.h"
34 MPIContainer_i::MPIContainer_i(int nbproc, int numproc,
36 PortableServer::POA_ptr poa,
38 : Engines_Container_i(orb,poa,containerName,0,0), MPIObject_i(nbproc,numproc)
40 _id = _poa->activate_object(this);
42 MESSAGE("[" << _numproc << "] containerName=" << _containerName);
44 _NS = SINGLETON_<SALOME_NamingService>::Instance() ;
45 ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting()) ;
46 _NS->init_orb( orb ) ;
48 Engines::Container_ptr pCont
49 = Engines::Container::_narrow(POA_Engines::MPIContainer::_this());
50 _NS->Register(pCont, _containerName.c_str());
53 // Root recupere les ior des container des autre process
54 Engines::MPIObject_var pobj = POA_Engines::MPIContainer::_this();
55 BCastIOR(_orb,pobj,true);
58 MPIContainer_i::~MPIContainer_i(void)
60 if( !handle_map.empty() ){
61 MESSAGE("[" << _numproc << "] MPIContainer_i::~MPIContainer_i: warning destroy a not empty container");
66 Engines::Component_ptr MPIContainer_i::load_impl(const char* nameToRegister,
67 const char* componentName)
70 Engines::Component_var iobject;
71 Engines::MPIObject_var pobj;
75 // Invocation du chargement du composant dans les autres process
76 for(ip= 1;ip<_nbproc;ip++)
77 (Engines::MPIContainer::_narrow((*_tior)[ip]))->load_impl(nameToRegister,
81 sprintf(cproc,"_%d",_numproc);
83 BEGIN_OF("[" << _numproc << "] MPIContainer_i::load_impl");
85 _numInstanceMutex.lock() ; // lock on the instance number
88 sprintf(_aNumI,"%d",_numInstance) ;
89 _numInstanceMutex.unlock() ;
91 string _impl_name = componentName;
92 string instanceName = string(nameToRegister) + "_inst_" + _aNumI + cproc;
94 string absolute_impl_name(_impl_name);
95 MESSAGE("[" << _numproc << "] absolute_impl_name=" << absolute_impl_name);
96 void * handle = dlopen(absolute_impl_name.c_str(), RTLD_LAZY);
98 MESSAGE("[" << _numproc << "] Can't load shared library : " << absolute_impl_name);
99 MESSAGE("[" << _numproc << "] error dlopen: " << dlerror());
100 return Engines::Component::_nil() ;
103 string factory_name = string(nameToRegister) + string("Engine_factory");
104 MESSAGE("[" << _numproc << "] factory_name=" << factory_name) ;
106 PortableServer::ObjectId * (*MPIComponent_factory) (int,int,
108 PortableServer::POA_ptr,
109 PortableServer::ObjectId *,
112 (PortableServer::ObjectId * (*) (int,int,
114 PortableServer::POA_ptr,
115 PortableServer::ObjectId *,
118 dlsym(handle, factory_name.c_str());
121 if ((error = dlerror()) != NULL){
122 // Try to load a sequential component
123 MESSAGE("[" << _numproc << "] Try to load a sequential component");
124 iobject = Engines_Container_i::load_impl(nameToRegister,componentName);
125 if( CORBA::is_nil(iobject) ) return Engines::Component::_duplicate(iobject);
128 // Instanciation du composant parallele
129 MESSAGE("[" << _numproc << "] Try to load a parallel component");
130 PortableServer::ObjectId * id = (MPIComponent_factory)
131 (_nbproc,_numproc,_orb, _poa, _id, instanceName.c_str(), nameToRegister);
132 // get reference from id
133 CORBA::Object_var o = _poa->id_to_reference(*id);
134 pobj = Engines::MPIObject::_narrow(o) ;
135 iobject = Engines::Component::_narrow(pobj) ;
138 // Root recupere les ior des composants des autre process
139 BCastIOR(_orb,pobj,false);
142 // utiliser + tard le registry ici :
143 // register the engine under the name containerName.dir/nameToRegister.object
144 string component_registerName = _containerName + "/" + nameToRegister;
145 _NS->Register(iobject, component_registerName.c_str()) ;
148 _numInstanceMutex.lock() ; // lock on the add on handle_map (necessary ?)
149 handle_map[instanceName] = handle;
150 _numInstanceMutex.unlock() ;
151 END_OF("[" <<_numproc << "] MPIContainer_i::load_impl");
152 return Engines::Component::_duplicate(iobject);
156 void MPIContainer_i::remove_impl(Engines::Component_ptr component_i)
159 Engines::Component_ptr cptr;
160 Engines::MPIObject_ptr pcptr;
161 Engines::MPIObject_ptr spcptr;
163 ASSERT(! CORBA::is_nil(component_i));
166 // Invocation de la destruction du composant dans les autres process
167 pcptr = (Engines::MPIObject_ptr)component_i;
168 for(ip= 1;ip<_nbproc;ip++){
169 spcptr = Engines::MPIObject::_narrow((*(pcptr->tior()))[ip]);
170 cptr = (Engines::Component_ptr)spcptr;
171 (Engines::MPIContainer::_narrow((*_tior)[ip]))->remove_impl(cptr);
175 string instanceName = component_i->instanceName() ;
176 MESSAGE("[" << _numproc << "] unload component " << instanceName);
177 component_i->destroy() ;
178 MESSAGE("[" << _numproc << "] test key handle_map");
179 _numInstanceMutex.lock() ; // lock on the remove on handle_map
180 if (handle_map[instanceName]) // if key does not exist, created & initialized null
182 remove_map[instanceName] = handle_map[instanceName] ;
184 else MESSAGE("[" << _numproc << "] no key handle_map");
185 handle_map.erase(instanceName) ;
186 _numInstanceMutex.unlock() ;
187 MESSAGE("[" << _numproc << "] list handle_map");
188 map<string, void *>::iterator im ;
189 for (im = handle_map.begin() ; im != handle_map.end() ; im ++)
191 MESSAGE("[" << _numproc << "] stay " << (*im).first);
195 void MPIContainer_i::finalize_removal()
199 MESSAGE("[" << _numproc << "] finalize unload : dlclose");
202 // Invocation de la destruction du composant dans les autres process
203 for(ip= 1;ip<_nbproc;ip++)
204 (Engines::MPIContainer::_narrow((*_tior)[ip]))->finalize_removal();
207 map<string, void *>::iterator im ;
208 _numInstanceMutex.lock() ; // lock on the explore remove_map & dlclose
209 for (im = remove_map.begin() ; im != remove_map.end() ; im ++)
211 void * handle = (*im).second ;
213 MESSAGE("[" << _numproc << "] dlclose " << (*im).first);
216 _numInstanceMutex.unlock() ;
217 MESSAGE("[" << _numproc << "] remove_map.clear()");