2 //=============================================================================
3 // File : Container_i.cxx
4 // Created : jeu jui 12 08:04:40 CEST 2001
5 // Author : Paul RASCLE, EDF - MARC TAJCHMAN, CEA
7 // Copyright : EDF 2001 - CEA 2001
9 //=============================================================================
11 #include <SALOMEconfig.h>
12 #include CORBA_SERVER_HEADER(SALOME_Component)
13 #include "SALOME_Container_i.hxx"
14 #include "SALOME_NamingService.hxx"
15 #include "Utils_SINGLETON.hxx"
21 #include "utilities.h"
23 bool _Sleeping = false ;
25 // Containers with name FactoryServer are started via rsh in LifeCycleCORBA
26 // Other Containers are started via start_impl of FactoryServer
28 extern "C" {void ActSigIntHandler() ; }
29 extern "C" {void SigIntHandler(int, siginfo_t *, void *) ; }
31 Engines_Container_i::Engines_Container_i (CORBA::ORB_ptr orb,
32 PortableServer::POA_ptr poa,
34 int argc , char* argv[] ) :
42 int i = strlen( _argv[ 0 ] ) - 1 ;
44 if ( _argv[ 0 ][ i ] == '/' ) {
45 _argv[ 0 ][ i+1 ] = '\0' ;
50 string hostname = GetHostname();
51 MESSAGE(hostname << " " << getpid() << " Engines_Container_i starting argc "
54 while ( _argv[ i ] ) {
55 MESSAGE(" argv" << i << " " << _argv[ i ]) ;
59 MESSAGE("SALOME_Container usage : SALOME_Container ServerName -ORBInitRef NameService=corbaname::hostname:tcpipPortNumber") ;
65 _containerName = "/Containers/";
66 if (strlen(containerName)== 0)
68 _containerName += hostname;
72 _containerName += hostname;
73 _containerName += "/" ;
74 _containerName += containerName;
77 _orb = CORBA::ORB::_duplicate(orb) ;
78 _poa = PortableServer::POA::_duplicate(poa) ;
79 MESSAGE("activate object");
80 _id = _poa->activate_object(this);
82 // _NS = new SALOME_NamingService(_orb);
83 _NS = SINGLETON_<SALOME_NamingService>::Instance() ;
84 ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting()) ;
85 _NS->init_orb( orb ) ;
87 Engines::Container_ptr pCont
88 = Engines::Container::_narrow(_this());
89 SCRUTE(_containerName);
90 _NS->Register(pCont, _containerName.c_str());
93 // Constructeur pour composant parallele : ne pas faire appel au naming service
94 Engines_Container_i::Engines_Container_i (CORBA::ORB_ptr orb,
95 PortableServer::POA_ptr poa,
100 string hostname = GetHostname();
103 _containerName = "/Containers/";
104 if (strlen(containerName)== 0)
106 _containerName += hostname;
110 _containerName += containerName;
113 _orb = CORBA::ORB::_duplicate(orb) ;
114 _poa = PortableServer::POA::_duplicate(poa) ;
118 Engines_Container_i::~Engines_Container_i()
120 MESSAGE("Container_i::~Container_i()");
123 char* Engines_Container_i::name()
125 return CORBA::string_dup(_containerName.c_str()) ;
128 char* Engines_Container_i::machineName()
130 string s = GetHostname();
131 MESSAGE("Engines_Container_i::machineName " << s);
132 return CORBA::string_dup(s.c_str()) ;
135 void Engines_Container_i::ping()
137 MESSAGE("Engines_Container_i::ping() pid "<< getpid());
140 bool Engines_Container_i::Kill_impl() {
141 MESSAGE("Engines_Container_i::Kill() pid "<< getpid() << " containerName "
142 << _containerName.c_str() << " machineName "
143 << GetHostname().c_str());
147 Engines::Container_ptr Engines_Container_i::start_impl(
148 const char* ContainerName ) {
149 MESSAGE("start_impl argc " << _argc << " ContainerName " << ContainerName
150 << hex << this << dec) ;
151 _numInstanceMutex.lock() ; // lock on the instance number
153 CORBA::Object_var obj = Engines::Container::_nil() ;
156 string cont("/Containers/");
157 cont += machineName() ;
159 cont += ContainerName;
160 INFOS(machineName() << " start_impl unknown container " << cont.c_str()
161 << " try to Resolve" );
162 obj = _NS->Resolve( cont.c_str() );
163 nilvar = CORBA::is_nil( obj ) ;
165 INFOS(machineName() << " start_impl unknown container "
169 catch (ServiceUnreachable&) {
170 INFOS(machineName() << "Caught exception: Naming Service Unreachable");
173 INFOS(machineName() << "Caught unknown exception.");
176 _numInstanceMutex.unlock() ;
177 MESSAGE("start_impl container found without runSession") ;
178 return Engines::Container::_narrow(obj);
181 while ( _argv[ i ] ) {
182 MESSAGE(" argv" << i << " " << _argv[ i ]) ;
185 // string shstr( "rsh -n " ) ;
186 // shstr += machineName() ;
188 // shstr += _argv[ 0 ] ;
189 // string shstr( _argv[ 0 ] ) ;
190 string shstr( "./runSession SALOME_Container " ) ;
191 shstr += ContainerName ;
194 shstr += _argv[ 2 ] ;
196 shstr += _argv[ 3 ] ;
198 shstr += " > /tmp/" ;
199 shstr += ContainerName ;
200 shstr += ".log 2>&1 &" ;
201 MESSAGE("system(" << shstr << ")") ;
202 int status = system( shstr.c_str() ) ;
204 INFOS("Engines_Container_i::start_impl runSession(SALOME_Container) failed (system command status -1)") ;
206 else if (status == 217) {
207 INFOS("Engines_Container_i::start_impl runSession(SALOME_Container) failed (system command status 217)") ;
209 INFOS(machineName() << " Engines_Container_i::start_impl runSession(SALOME_Container) done");
213 string anExe( _argv[ 0 ] ) ;
214 anExe += "runSession" ;
216 args[ 0 ] = "runSession" ;
217 args[ 1 ] = "SALOME_Container" ;
218 args[ 2 ] = strdup( ContainerName ) ;
219 args[ 3 ] = strdup( _argv[ 2 ] ) ;
220 args[ 4 ] = strdup( _argv[ 3 ] ) ;
222 MESSAGE("execl(" << anExe.c_str() << " , " << args[ 0 ] << " , "
223 << args[ 1 ] << " , " << args[ 2 ] << " , " << args[ 3 ]
224 << " , " << args[ 4 ] << ")") ;
225 int status = execv( anExe.c_str() , args ) ;
227 INFOS("Engines_Container_i::start_impl execl failed (system command status -1)") ;
228 perror( "Engines_Container_i::start_impl execl error ") ;
231 INFOS(machineName() << " Engines_Container_i::start_impl execl done");
237 obj = Engines::Container::_nil() ;
239 string cont("/Containers/");
240 cont += machineName() ;
242 cont += ContainerName;
245 while ( nilvar && count >= 0) {
247 obj = _NS->Resolve(cont.c_str());
248 nilvar = CORBA::is_nil( obj ) ;
250 INFOS(count << ". " << machineName()
251 << " start_impl unknown container " << cont.c_str());
255 _numInstanceMutex.unlock() ;
257 MESSAGE("start_impl container found after runSession(SALOME_Container)") ;
259 return Engines::Container::_narrow(obj);
261 catch (ServiceUnreachable&) {
262 INFOS(machineName() << "Caught exception: Naming Service Unreachable");
265 INFOS(machineName() << "Caught unknown exception.");
267 _numInstanceMutex.unlock() ;
268 MESSAGE("start_impl container not found after runSession(SALOME_Container)") ;
269 return Engines::Container::_nil() ;
272 Engines::Component_ptr Engines_Container_i::load_impl
273 (const char* nameToRegister,
274 const char* componentName)
276 BEGIN_OF("Container_i::load_impl");
278 _numInstanceMutex.lock() ; // lock on the instance number
281 sprintf(_aNumI,"%d",_numInstance) ;
283 string _impl_name = componentName;
284 string _nameToRegister = nameToRegister;
285 string instanceName = _nameToRegister + "_inst_" + _aNumI ;
286 //SCRUTE(instanceName);
288 //string absolute_impl_name = _library_path + "lib" + _impl_name + ".so";
289 string absolute_impl_name(_impl_name);
290 // SCRUTE(absolute_impl_name);
292 handle = dlopen(absolute_impl_name.c_str(), RTLD_LAZY);
295 INFOS("Can't load shared library : " << absolute_impl_name);
296 INFOS("error dlopen: " << dlerror());
297 _numInstanceMutex.unlock() ;
298 return Engines::Component::_nil() ;
301 string factory_name = _nameToRegister + string("Engine_factory");
302 // SCRUTE(factory_name) ;
304 typedef PortableServer::ObjectId * (*FACTORY_FUNCTION)
306 PortableServer::POA_ptr,
307 PortableServer::ObjectId *,
310 // typedef PortableServer::ObjectId * (*FACTORY_FUNCTION_SUPERV)
312 // PortableServer::POA_ptr,
313 // PortableServer::ObjectId *,
318 FACTORY_FUNCTION Component_factory = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
319 // FACTORY_FUNCTION_SUPERV Component_factory_superv = (FACTORY_FUNCTION_SUPERV) Component_factory ;
321 // PortableServer::ObjectId * (*Component_factory) (CORBA::ORB_ptr,
322 // PortableServer::POA_ptr,
323 // PortableServer::ObjectId *,
326 // (PortableServer::ObjectId * (*) (CORBA::ORB_ptr,
327 // PortableServer::POA_ptr,
328 // PortableServer::ObjectId *,
331 // dlsym(handle, factory_name.c_str());
334 if ((error = dlerror()) != NULL)
336 INFOS("Can't resolve symbol: " + factory_name);
338 _numInstanceMutex.unlock() ;
339 return Engines::Component::_nil() ;
342 // Instanciate required CORBA object
343 PortableServer::ObjectId * id ;
344 // if ( factory_name == "SupervisionEngine_factory" ) { // for Python ...
345 // id = (Component_factory_superv) (_orb, _poa, _id, instanceName.c_str(),
346 // _nameToRegister.c_str(), _argc , _argv );
349 id = (Component_factory) (_orb, _poa, _id, instanceName.c_str(),
350 _nameToRegister.c_str());
352 // get reference from id
353 CORBA::Object_var o = _poa->id_to_reference(*id);
354 Engines::Component_var iobject = Engines::Component::_narrow(o) ;
356 // _numInstanceMutex.lock() ; // lock on the add on handle_map (necessary ?)
357 // register the engine under the name containerName.dir/nameToRegister.object
358 string component_registerName = _containerName + "/" + _nameToRegister;
359 _NS->Register(iobject, component_registerName.c_str()) ;
361 //Jr _numInstanceMutex.lock() ; // lock on the add on handle_map (necessary ?)
362 handle_map[instanceName] = handle;
363 _numInstanceMutex.unlock() ;
364 // END_OF("Container_i::load_impl");
365 return Engines::Component::_duplicate(iobject);
368 void Engines_Container_i::remove_impl(Engines::Component_ptr component_i)
370 ASSERT(! CORBA::is_nil(component_i));
371 string instanceName = component_i->instanceName() ;
372 MESSAGE("unload component " << instanceName);
373 component_i->destroy() ;
374 MESSAGE("test key handle_map");
375 _numInstanceMutex.lock() ; // lock on the remove on handle_map
376 if (handle_map[instanceName]) // if key does not exist, created & initialized null
378 remove_map[instanceName] = handle_map[instanceName] ;
380 else MESSAGE("pas d'entree handle_map");
381 handle_map.erase(instanceName) ;
382 _numInstanceMutex.unlock() ;
383 MESSAGE("contenu handle_map");
384 map<string, void *>::iterator im ;
385 for (im = handle_map.begin() ; im != handle_map.end() ; im ++)
387 MESSAGE("reste " << (*im).first);
391 void Engines_Container_i::finalize_removal()
393 MESSAGE("finalize unload : dlclose");
394 map<string, void *>::iterator im ;
395 _numInstanceMutex.lock() ; // lock on the explore remove_map & dlclose
396 for (im = remove_map.begin() ; im != remove_map.end() ; im ++)
398 void * handle = (*im).second ;
400 MESSAGE("dlclose " << (*im).first);
403 _numInstanceMutex.unlock() ;
404 MESSAGE("remove_map.clear()");
407 void ActSigIntHandler() {
408 struct sigaction SigIntAct ;
409 SigIntAct.sa_sigaction = &SigIntHandler ;
410 SigIntAct.sa_flags = SA_SIGINFO ;
411 if ( sigaction( SIGINT , &SigIntAct, NULL ) ) {
412 perror("SALOME_Container main ") ;
416 INFOS("SigIntHandler activated") ;
420 void SigIntHandler(int what , siginfo_t * siginfo ,
422 MESSAGE("SigIntHandler what " << what << endl
423 << " si_signo " << siginfo->si_signo << endl
424 << " si_code " << siginfo->si_code << endl
425 << " si_pid " << siginfo->si_pid) ;
428 INFOS("SigIntHandler END sleeping.")
429 MESSAGE("SigIntHandler END sleeping.") ;
435 INFOS("SigIntHandler BEGIN sleeping.")
436 MESSAGE("SigIntHandler BEGIN sleeping.") ;
442 INFOS("SigIntHandler LEAVE sleeping after " << count << " s.")
443 MESSAGE("SigIntHandler LEAVE sleeping after " << count << " s.") ;