1 // SALOME Container : implementation of container and engine for Kernel
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 : Container_i.cxx
25 // Author : Paul RASCLE, EDF - MARC TAJCHMAN, CEA
29 //#define private public
30 #include <SALOMEconfig.h>
32 #include CORBA_SERVER_HEADER(SALOME_Component)
34 #include <SALOME_Component.hh>
36 #include "SALOME_Container_i.hxx"
37 #include "SALOME_Component_i.hxx"
38 #include "SALOME_NamingService.hxx"
46 #include "../../adm/win32/SALOME_WNT.hxx"
52 #include "Container_init_python.hxx"
54 #include "utilities.h"
57 bool _Sleeping = false ;
59 // Needed by multi-threaded Python
64 // Containers with name FactoryServer are started via rsh in LifeCycleCORBA
65 // Other Containers are started via start_impl of FactoryServer
67 extern "C" {void ActSigIntHandler() ; }
69 extern "C" {void SigIntHandler(int, siginfo_t *, void *) ; }
71 extern "C" {void SigIntHandler( int ) ; }
75 const char *Engines_Container_i::_defaultContainerName="FactoryServer";
76 map<std::string, int> Engines_Container_i::_cntInstances_map;
77 map<std::string, void *> Engines_Container_i::_library_map;
78 map<std::string, void *> Engines_Container_i::_toRemove_map;
79 omni_mutex Engines_Container_i::_numInstanceMutex ;
81 //=============================================================================
83 * Default constructor, not for use
85 //=============================================================================
87 Engines_Container_i::Engines_Container_i () :
92 //=============================================================================
96 //=============================================================================
98 Engines_Container_i::Engines_Container_i (CORBA::ORB_ptr orb,
99 PortableServer::POA_ptr poa,
100 char *containerName ,
101 int argc , char* argv[],
103 bool isServantAloneInProcess
105 _numInstance(0),_isServantAloneInProcess(isServantAloneInProcess)
107 _pid = (long)getpid();
117 int i = strlen( _argv[ 0 ] ) - 1 ;
120 if ( _argv[ 0 ][ i ] == '/' )
122 _argv[ 0 ][ i+1 ] = '\0' ;
127 string hostname = GetHostname();
128 MESSAGE(hostname << " " << getpid() << " Engines_Container_i starting argc "
129 << _argc << " Thread " << pthread_self() ) ;
133 MESSAGE(" argv" << i << " " << _argv[ i ]) ;
139 INFOS("SALOME_Container usage : SALOME_Container ServerName");
143 _isSupervContainer = false;
144 if (strcmp(argv[1],"SuperVisionContainer") == 0) _isSupervContainer = true;
146 _containerName = BuildContainerNameForNS(containerName,hostname.c_str());
148 _orb = CORBA::ORB::_duplicate(orb) ;
149 _poa = PortableServer::POA::_duplicate(poa) ;
151 // Pour les containers paralleles: il ne faut pas enregistrer et activer
152 // le container generique, mais le container specialise
156 _id = _poa->activate_object(this);
157 _NS = new SALOME_NamingService();
158 _NS->init_orb( CORBA::ORB::_duplicate(_orb) ) ;
159 CORBA::Object_var obj=_poa->id_to_reference(*_id);
160 Engines::Container_var pCont
161 = Engines::Container::_narrow(obj);
162 SCRUTE(_containerName);
163 _NS->Register(pCont, _containerName.c_str());
166 // import SALOME_Container
167 // pycont = SALOME_Container.SALOME_Container_i(containerIORStr)
169 CORBA::String_var sior = _orb->object_to_string(pCont);
170 string myCommand="pyCont = SALOME_Container.SALOME_Container_i('";
171 myCommand += _containerName + "','";
176 if (!_isSupervContainer)
178 Py_ACQUIRE_NEW_THREAD;
179 PyRun_SimpleString("import SALOME_Container\n");
180 PyRun_SimpleString((char*)myCommand.c_str());
181 Py_RELEASE_NEW_THREAD;
186 //=============================================================================
190 //=============================================================================
192 Engines_Container_i::~Engines_Container_i()
194 MESSAGE("Container_i::~Container_i()");
198 //=============================================================================
200 * CORBA attribute: Container name (see constructor)
202 //=============================================================================
204 char* Engines_Container_i::name()
206 return CORBA::string_dup(_containerName.c_str()) ;
209 //=============================================================================
211 * CORBA method: Get the hostName of the Container (without domain extensions)
213 //=============================================================================
215 char* Engines_Container_i::getHostName()
217 string s = GetHostname();
218 MESSAGE("Engines_Container_i::getHostName " << s);
219 return CORBA::string_dup(s.c_str()) ;
222 //=============================================================================
224 * CORBA method: Get the PID (process identification) of the Container
226 //=============================================================================
228 CORBA::Long Engines_Container_i::getPID()
230 return (CORBA::Long)getpid();
233 //=============================================================================
235 * CORBA method: check if servant is still alive
237 //=============================================================================
239 void Engines_Container_i::ping()
241 MESSAGE("Engines_Container_i::ping() pid "<< getpid());
244 //=============================================================================
246 * CORBA method, oneway: Server shutdown.
247 * - Container name removed from naming service,
248 * - servant deactivation,
249 * - orb shutdown if no other servants in the process
251 //=============================================================================
253 void Engines_Container_i::Shutdown()
255 MESSAGE("Engines_Container_i::Shutdown()");
256 _NS->Destroy_Name(_containerName.c_str());
258 //_poa->deactivate_object(*_id);
259 if(_isServantAloneInProcess)
264 //=============================================================================
266 * CORBA method: load a new component class (Python or C++ implementation)
267 * \param componentName like COMPONENT
268 * try to make a Python import of COMPONENT,
269 * then a lib open of libCOMPONENTEngine.so
270 * \return true if dlopen successfull or already done, false otherwise
272 //=============================================================================
275 Engines_Container_i::load_component_Library(const char* componentName)
278 string aCompName = componentName;
280 // --- try dlopen C++ component
282 string impl_name = string ("lib") + aCompName + string("Engine.so");
285 _numInstanceMutex.lock(); // lock to be alone
286 // (see decInstanceCnt, finalize_removal))
287 if (_toRemove_map[impl_name]) _toRemove_map.erase(impl_name);
288 if (_library_map[impl_name])
290 MESSAGE("Library " << impl_name << " already loaded");
291 _numInstanceMutex.unlock();
297 handle = dlopen( impl_name.c_str() , RTLD_LAZY ) ;
299 handle = dlopen( impl_name.c_str() , 0 ) ;
303 _library_map[impl_name] = handle;
304 _numInstanceMutex.unlock();
309 INFOS("Can't load shared library : " << impl_name);
310 INFOS("error dlopen: " << dlerror());
312 _numInstanceMutex.unlock();
314 // --- try import Python component
316 INFOS("try import Python component "<<componentName);
317 if (_isSupervContainer)
319 INFOS("Supervision Container does not support Python Component Engines");
322 if (_library_map[aCompName])
324 return true; // Python Component, already imported
328 Py_ACQUIRE_NEW_THREAD;
329 PyObject *mainmod = PyImport_AddModule("__main__");
330 PyObject *globals = PyModule_GetDict(mainmod);
331 PyObject *pyCont = PyDict_GetItemString(globals, "pyCont");
332 PyObject *result = PyObject_CallMethod(pyCont,
335 int ret= PyInt_AsLong(result);
337 Py_RELEASE_NEW_THREAD;
339 if (ret) // import possible: Python component
341 _library_map[aCompName] = (void *)pyCont; // any non O value OK
342 MESSAGE("import Python: "<<aCompName<<" OK");
349 //=============================================================================
351 * CORBA method: Creates a new servant instance of a component.
352 * The servant registers itself to naming service and Registry.
353 * \param genericRegisterName Name of the component instance to register
354 * in Registry & Name Service (without _inst_n suffix)
355 * \param studyId 0 for multiStudy instance,
356 * study Id (>0) otherwise
357 * \return a loaded component
359 //=============================================================================
361 Engines::Component_ptr
362 Engines_Container_i::create_component_instance(const char*genericRegisterName,
367 INFOS("studyId must be > 0 for mono study instance, =0 for multiStudy");
368 return Engines::Component::_nil() ;
371 Engines::Component_var iobject = Engines::Component::_nil() ;
373 string aCompName = genericRegisterName;
374 if (_library_map[aCompName]) // Python component
376 if (_isSupervContainer)
378 INFOS("Supervision Container does not support Python Component Engines");
379 return Engines::Component::_nil();
381 _numInstanceMutex.lock() ; // lock on the instance number
383 int numInstance = _numInstance ;
384 _numInstanceMutex.unlock() ;
387 sprintf( aNumI , "%d" , numInstance ) ;
388 string instanceName = aCompName + "_inst_" + aNumI ;
389 string component_registerName =
390 _containerName + "/" + instanceName;
392 Py_ACQUIRE_NEW_THREAD;
393 PyObject *mainmod = PyImport_AddModule("__main__");
394 PyObject *globals = PyModule_GetDict(mainmod);
395 PyObject *pyCont = PyDict_GetItemString(globals, "pyCont");
396 PyObject *result = PyObject_CallMethod(pyCont,
397 "create_component_instance",
400 instanceName.c_str(),
402 string iors = PyString_AsString(result);
404 Py_RELEASE_NEW_THREAD;
406 CORBA::Object_var obj = _orb->string_to_object(iors.c_str());
407 iobject = Engines::Component::_narrow( obj ) ;
408 return iobject._retn();
413 string impl_name = string ("lib") + genericRegisterName +string("Engine.so");
414 void* handle = _library_map[impl_name];
417 INFOS("shared library " << impl_name <<"must be loaded before instance");
418 return Engines::Component::_nil() ;
422 iobject = createInstance(genericRegisterName,
425 return iobject._retn();
429 //=============================================================================
431 * CORBA method: Finds a servant instance of a component
432 * \param registeredName Name of the component in Registry or Name Service,
433 * without instance suffix number
434 * \param studyId 0 if instance is not associated to a study,
435 * >0 otherwise (== study id)
436 * \return the first instance found with same studyId
438 //=============================================================================
440 Engines::Component_ptr
441 Engines_Container_i::find_component_instance( const char* registeredName,
444 Engines::Component_var anEngine = Engines::Component::_nil();
445 map<string,Engines::Component_var>::iterator itm =_listInstances_map.begin();
446 while (itm != _listInstances_map.end())
448 string instance = (*itm).first;
450 if (instance.find(registeredName) == 0)
452 anEngine = (*itm).second;
453 if (studyId == anEngine->getStudyId())
455 return anEngine._retn();
460 return anEngine._retn();
463 //=============================================================================
465 * CORBA method: find or create an instance of the component (servant),
466 * load a new component class (dynamic library) if required,
467 * ---- FOR COMPATIBILITY WITH 2.2 ----
468 * ---- USE ONLY FOR MULTISTUDY INSTANCES ! --------
469 * The servant registers itself to naming service and Registry.
470 * \param genericRegisterName Name of the component to register
471 * in Registry & Name Service
472 * \param componentName Name of the constructed library of the component
473 * \return a loaded component
475 //=============================================================================
477 Engines::Component_ptr
478 Engines_Container_i::load_impl( const char* genericRegisterName,
479 const char* componentName )
481 string impl_name = string ("lib") + genericRegisterName +string("Engine.so");
482 Engines::Component_var iobject = Engines::Component::_nil() ;
483 if (load_component_Library(genericRegisterName))
484 iobject = find_or_create_instance(genericRegisterName, impl_name);
485 return iobject._retn();
489 //=============================================================================
491 * CORBA method: Stops the component servant, and deletes all related objects
492 * \param component_i Component to be removed
494 //=============================================================================
496 void Engines_Container_i::remove_impl(Engines::Component_ptr component_i)
498 ASSERT(! CORBA::is_nil(component_i));
499 string instanceName = component_i->instanceName() ;
500 MESSAGE("unload component " << instanceName);
501 _listInstances_map.erase(instanceName);
502 component_i->destroy() ;
503 _NS->Destroy_Name(instanceName.c_str());
506 //=============================================================================
508 * CORBA method: Discharges unused libraries from the container.
510 //=============================================================================
512 void Engines_Container_i::finalize_removal()
514 MESSAGE("finalize unload : dlclose");
515 _numInstanceMutex.lock(); // lock to be alone
516 // (see decInstanceCnt, load_component_Library)
517 map<string, void *>::iterator ith;
518 for (ith = _toRemove_map.begin(); ith != _toRemove_map.end(); ith++)
520 void *handle = (*ith).second;
521 string impl_name= (*ith).first;
526 // dlclose(handle); // SALOME unstable after ...
527 // _library_map.erase(impl_name);
530 _toRemove_map.clear();
531 _numInstanceMutex.unlock();
534 //=============================================================================
536 * CORBA method: Kill the container process with exit(0).
537 * To remove : never returns !
539 //=============================================================================
541 bool Engines_Container_i::Kill_impl()
543 MESSAGE("Engines_Container_i::Kill() pid "<< getpid() << " containerName "
544 << _containerName.c_str() << " machineName "
545 << GetHostname().c_str());
546 INFOS("===============================================================");
547 INFOS("= REMOVE calls to Kill_impl in C++ container =");
548 INFOS("===============================================================");
554 //=============================================================================
556 * C++ method: Finds an already existing servant instance of a component, or
557 * create an instance.
558 * ---- USE ONLY FOR MULTISTUDY INSTANCES ! --------
559 * \param genericRegisterName Name of the component instance to register
560 * in Registry & Name Service,
561 * (without _inst_n suffix, like "COMPONENT")
562 * \param componentLibraryName like "libCOMPONENTEngine.so"
563 * \return a loaded component
565 * example with names:
566 * aGenRegisterName = COMPONENT (= first argument)
567 * impl_name = libCOMPONENTEngine.so (= second argument)
568 * _containerName = /Containers/cli76ce/FactoryServer
569 * factoryName = COMPONENTEngine_factory
570 * component_registerBase = /Containers/cli76ce/FactoryServer/COMPONENT
572 * instanceName = COMPONENT_inst_1
573 * component_registerName = /Containers/cli76ce/FactoryServer/COMPONENT_inst_1
575 //=============================================================================
577 Engines::Component_ptr
578 Engines_Container_i::find_or_create_instance(string genericRegisterName,
579 string componentLibraryName)
581 string aGenRegisterName = genericRegisterName;
582 string impl_name = componentLibraryName;
583 void* handle = _library_map[impl_name];
586 INFOS("shared library " << impl_name <<"must be loaded before instance");
587 return Engines::Component::_nil() ;
591 // --- find a registered instance in naming service, or create
593 string component_registerBase =
594 _containerName + "/" + aGenRegisterName;
595 Engines::Component_var iobject = Engines::Component::_nil() ;
598 CORBA::Object_var obj =
599 _NS->ResolveFirst( component_registerBase.c_str());
600 if ( CORBA::is_nil( obj ) )
602 iobject = createInstance(genericRegisterName,
604 0); // force multiStudy instance here !
608 iobject = Engines::Component::_narrow( obj ) ;
609 Engines_Component_i *servant =
610 dynamic_cast<Engines_Component_i*>
611 (_poa->reference_to_servant(iobject));
613 int studyId = servant->getStudyId();
614 ASSERT (studyId >= 0);
615 if (studyId == 0) // multiStudy instance, OK
618 MESSAGE(component_registerBase.c_str()<<" already bound");
620 else // monoStudy instance: NOK
622 iobject = Engines::Component::_nil();
623 INFOS("load_impl & find_component_instance methods "
624 << "NOT SUITABLE for mono study components");
630 INFOS( "Container_i::load_impl catched" ) ;
632 return iobject._retn();
636 //=============================================================================
638 * C++ method: create a servant instance of a component.
639 * \param genericRegisterName Name of the component instance to register
640 * in Registry & Name Service,
641 * (without _inst_n suffix, like "COMPONENT")
642 * \param handle loaded library handle
643 * \param studyId 0 for multiStudy instance,
644 * study Id (>0) otherwise
645 * \return a loaded component
647 * example with names:
648 * aGenRegisterName = COMPONENT (= first argument)
649 * _containerName = /Containers/cli76ce/FactoryServer
650 * factoryName = COMPONENTEngine_factory
651 * component_registerBase = /Containers/cli76ce/FactoryServer/COMPONENT
652 * instanceName = COMPONENT_inst_1
653 * component_registerName = /Containers/cli76ce/FactoryServer/COMPONENT_inst_1
655 //=============================================================================
657 Engines::Component_ptr
658 Engines_Container_i::createInstance(string genericRegisterName,
662 // --- find the factory
664 string aGenRegisterName = genericRegisterName;
665 string factory_name = aGenRegisterName + string("Engine_factory");
666 SCRUTE(factory_name) ;
668 typedef PortableServer::ObjectId * (*FACTORY_FUNCTION)
670 PortableServer::POA_ptr,
671 PortableServer::ObjectId *,
675 FACTORY_FUNCTION Component_factory
676 = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
679 if ( (error = dlerror() ) != NULL)
681 INFOS("Can't resolve symbol: " + factory_name);
683 return Engines::Component::_nil() ;
686 // --- create instance
688 Engines::Component_var iobject = Engines::Component::_nil() ;
692 _numInstanceMutex.lock() ; // lock on the instance number
694 int numInstance = _numInstance ;
695 _numInstanceMutex.unlock() ;
698 sprintf( aNumI , "%d" , numInstance ) ;
699 string instanceName = aGenRegisterName + "_inst_" + aNumI ;
700 string component_registerName =
701 _containerName + "/" + instanceName;
703 // --- Instanciate required CORBA object
705 PortableServer::ObjectId *id ; //not owner, do not delete (nore use var)
706 id = (Component_factory) ( _orb, _poa, _id, instanceName.c_str(),
707 aGenRegisterName.c_str() ) ;
709 // --- get reference & servant from id
711 CORBA::Object_var obj = _poa->id_to_reference(*id);
712 iobject = Engines::Component::_narrow( obj ) ;
714 Engines_Component_i *servant =
715 dynamic_cast<Engines_Component_i*>(_poa->reference_to_servant(iobject));
717 //SCRUTE(servant->pd_refCount);
718 servant->_remove_ref(); // compensate previous id_to_reference
719 //SCRUTE(servant->pd_refCount);
720 _listInstances_map[instanceName] = iobject;
721 _cntInstances_map[aGenRegisterName] += 1;
722 SCRUTE(aGenRegisterName);
723 SCRUTE(_cntInstances_map[aGenRegisterName]);
724 //SCRUTE(servant->pd_refCount);
725 bool ret_studyId = servant->setStudyId(studyId);
728 // --- register the engine under the name
729 // containerName(.dir)/instanceName(.object)
731 _NS->Register( iobject , component_registerName.c_str() ) ;
732 MESSAGE( component_registerName.c_str() << " bound" ) ;
736 INFOS( "Container_i::createInstance exception catched" ) ;
738 return iobject._retn();
741 //=============================================================================
745 //=============================================================================
747 void Engines_Container_i::decInstanceCnt(string genericRegisterName)
749 string aGenRegisterName =genericRegisterName;
750 MESSAGE("Engines_Container_i::decInstanceCnt " << aGenRegisterName);
751 ASSERT(_cntInstances_map[aGenRegisterName] > 0);
752 _numInstanceMutex.lock(); // lock to be alone
753 // (see finalize_removal, load_component_Library)
754 _cntInstances_map[aGenRegisterName] -= 1;
755 SCRUTE(_cntInstances_map[aGenRegisterName]);
756 if (_cntInstances_map[aGenRegisterName] == 0)
759 Engines_Component_i::GetDynLibraryName(aGenRegisterName.c_str());
761 void* handle = _library_map[impl_name];
763 _toRemove_map[impl_name] = handle;
765 _numInstanceMutex.unlock();
768 //=============================================================================
770 * Retrieves only with container naming convention if it is a python container
772 //=============================================================================
774 bool Engines_Container_i::isPythonContainer(const char* ContainerName)
777 int len=strlen(ContainerName);
779 if(strcmp(ContainerName+len-2,"Py")==0)
784 //=============================================================================
786 * Returns string = container path + name, to use in Naming service
788 //=============================================================================
790 string Engines_Container_i::BuildContainerNameForNS(const char *ContainerName,
791 const char *hostname)
793 string ret="/Containers/";
796 if (strlen(ContainerName)== 0)
797 ret+=_defaultContainerName;
799 ret += ContainerName;
803 //=============================================================================
807 //=============================================================================
809 void ActSigIntHandler()
812 struct sigaction SigIntAct ;
813 SigIntAct.sa_sigaction = &SigIntHandler ;
814 SigIntAct.sa_flags = SA_SIGINFO ;
817 // DEBUG 03.02.2005 : the first parameter of sigaction is not a mask of signals (SIGINT | SIGUSR1) :
818 // it must be only one signal ===> one call for SIGINT and an other one for SIGUSR1
820 if ( sigaction( SIGINT , &SigIntAct, NULL ) ) {
821 perror("SALOME_Container main ") ;
824 if ( sigaction( SIGUSR1 , &SigIntAct, NULL ) ) {
825 perror("SALOME_Container main ") ;
828 INFOS(pthread_self() << "SigIntHandler activated") ;
830 signal( SIGINT, SigIntHandler );
831 signal( SIGUSR1, SigIntHandler );
839 void SigIntHandler(int what , siginfo_t * siginfo ,
842 MESSAGE(pthread_self() << "SigIntHandler what " << what << endl
843 << " si_signo " << siginfo->si_signo << endl
844 << " si_code " << siginfo->si_code << endl
845 << " si_pid " << siginfo->si_pid) ;
848 MESSAGE("SigIntHandler END sleeping.") ;
853 if ( siginfo->si_signo == SIGUSR1 ) {
858 MESSAGE("SigIntHandler BEGIN sleeping.") ;
864 MESSAGE("SigIntHandler LEAVE sleeping after " << count << " s.") ;
870 void SigIntHandler( int what ) {
871 MESSAGE( pthread_self() << "SigIntHandler what " << what << endl );
874 MESSAGE("SigIntHandler END sleeping.") ;
879 if ( what == SIGUSR1 ) {
884 MESSAGE("SigIntHandler BEGIN sleeping.") ;
890 MESSAGE("SigIntHandler LEAVE sleeping after " << count << " s.") ;
897 //=============================================================================
899 * CORBA method: Create one instance of componentName component
900 * and register it as genericRegisterName in naming service
902 //=============================================================================
904 // Engines::Component_ptr Engines_Container_i::instance( const char* genericRegisterName,
905 // const char* componentName )
907 // _numInstanceMutex.lock() ; // lock on the instance number
908 // BEGIN_OF( "Container_i::instance " << componentName ) ;
910 // string _genericRegisterName = genericRegisterName;
911 // string component_registerName = _containerName + "/" + _genericRegisterName;
913 // Engines::Component_var iobject = Engines::Component::_nil() ;
917 // CORBA::Object_var obj = _NS->Resolve( component_registerName.c_str() ) ;
918 // if (! CORBA::is_nil( obj ) )
920 // MESSAGE( "Container_i::instance " << component_registerName.c_str() << " already registered" ) ;
921 // iobject = Engines::Component::_narrow( obj ) ;
925 // string _compo_name = componentName;
926 // string _impl_name = "lib" + _compo_name + "Engine.so";
927 // SCRUTE(_impl_name);
930 // handle = dlopen( _impl_name.c_str() , RTLD_LAZY ) ;
934 // string factory_name = _compo_name + "Engine_factory";
935 // SCRUTE(factory_name) ;
937 // typedef PortableServer::ObjectId * (*FACTORY_FUNCTION)
939 // PortableServer::POA_ptr,
940 // PortableServer::ObjectId *,
943 // FACTORY_FUNCTION Component_factory = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
946 // if ( (error = dlerror() ) == NULL)
948 // // Instanciate required CORBA object
951 // sprintf( _aNumI , "%d" , _numInstance ) ;
952 // string instanceName = _compo_name + "_inst_" + _aNumI ;
953 // SCRUTE(instanceName);
955 // PortableServer::ObjectId * id ;
956 // id = (Component_factory) ( _orb, _poa, _id, instanceName.c_str() ,
957 // _genericRegisterName.c_str() ) ;
958 // // get reference from id
959 // obj = _poa->id_to_reference(*id);
960 // iobject = Engines::Component::_narrow( obj ) ;
962 // // register the engine under the name containerName.dir/genericRegisterName.object
963 // _NS->Register( iobject , component_registerName.c_str() ) ;
964 // MESSAGE( "Container_i::instance " << component_registerName.c_str() << " registered" ) ;
965 // _handle_map[instanceName] = handle;
969 // INFOS("Can't resolve symbol: " + factory_name);
975 // INFOS("Can't load shared library : " << _impl_name);
976 // INFOS("error dlopen: " << dlerror());
982 // INFOS( "Container_i::instance exception caught" ) ;
984 // END_OF("Container_i::instance");
985 // _numInstanceMutex.unlock() ;
986 // return Engines::Component::_duplicate(iobject);
989 //=============================================================================
991 * CORBA attribute: Machine Name (hostname without domain extensions)
993 //=============================================================================
995 // char* Engines_Container_i::machineName()
997 // string s = GetHostname();
998 // MESSAGE("Engines_Container_i::machineName " << s);
999 // return CORBA::string_dup(s.c_str()) ;