1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 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.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // SALOME_ParallelContainer : implementation of container and engine for ParallelKernel
23 // File : SALOME_ParallelContainer_i.cxx
24 // Author : Andr� RIBES, EDF
25 // Author : Paul RASCLE, EDF - MARC TAJCHMAN, CEA
27 #include <SALOMEconfig.h>
30 #include <SALOME_Component.hxx>
32 #include "SALOME_ParallelContainer_i.hxx"
34 #include "SALOME_Component_i.hxx"
36 #include "SALOME_FileRef_i.hxx"
37 #include "SALOME_FileTransfer_i.hxx"
38 #include "SALOME_NamingService.hxx"
47 #include "../../adm/win32/SALOME_WNT.hxx"
53 #include <paco_omni.h>
54 #include "utilities.h"
57 bool _Sleeping = false ;
59 // Containers with name FactoryServer are started via rsh in LifeCycleCORBA
60 // Other Containers are started via start_impl of FactoryServer
62 extern "C" {void ActSigIntHandler() ; }
64 extern "C" {void SigIntHandler(int, siginfo_t *, void *) ; }
66 extern "C" {void SigIntHandler( int ) ; }
70 map<std::string, int> Engines_Parallel_Container_i::_cntInstances_map;
71 map<std::string, void *> Engines_Parallel_Container_i::_library_map;
72 map<std::string, void *> Engines_Parallel_Container_i::_toRemove_map;
73 omni_mutex Engines_Parallel_Container_i::_numInstanceMutex ;
75 //=============================================================================
77 * Default constructor, not for use
79 //=============================================================================
81 Engines_Parallel_Container_i::Engines_Parallel_Container_i (CORBA::ORB_ptr orb,
84 InterfaceParallel_impl(orb,ior,rank),
85 Engines::Container_serv(orb,ior,rank),
90 //=============================================================================
94 //=============================================================================
96 Engines_Parallel_Container_i::Engines_Parallel_Container_i (CORBA::ORB_ptr orb,
99 PortableServer::POA_ptr poa,
100 char *containerName ,
101 int argc , char* argv[],
103 bool isServantAloneInProcess
105 InterfaceParallel_impl(orb,ior,rank),
106 Engines::Container_serv(orb,ior,rank),
107 _numInstance(0),_isServantAloneInProcess(isServantAloneInProcess)
109 _pid = (long)getpid();
117 string hostname = Kernel_Utils::GetHostname();
119 _orb = CORBA::ORB::_duplicate(orb) ;
120 _poa = PortableServer::POA::_duplicate(poa) ;
121 _NS = new SALOME_NamingService();
122 _NS->init_orb( CORBA::ORB::_duplicate(_orb) );
123 _containerName = _NS->BuildContainerNameForNS(containerName, hostname.c_str());
125 fileTransfer_i* aFileTransfer = new fileTransfer_i();
126 _fileTransfer = Engines::fileTransfer::_narrow(aFileTransfer->_this());
129 //=============================================================================
133 //=============================================================================
135 Engines_Parallel_Container_i::~Engines_Parallel_Container_i()
137 MESSAGE("Container_i::~Container_i()");
141 //=============================================================================
143 * CORBA attribute: Container name (see constructor)
145 //=============================================================================
147 char* Engines_Parallel_Container_i::name()
149 return CORBA::string_dup(_containerName.c_str()) ;
152 //=============================================================================
154 * CORBA method: Get the hostName of the Container (without domain extensions)
156 //=============================================================================
158 char* Engines_Parallel_Container_i::getHostName()
160 string s = Kernel_Utils::GetHostname();
161 MESSAGE("Engines_Parallel_Container_i::getHostName " << s);
162 return CORBA::string_dup(s.c_str()) ;
165 //=============================================================================
167 * CORBA method: Get the PID (process identification) of the Container
169 //=============================================================================
171 CORBA::Long Engines_Parallel_Container_i::getPID()
173 return (CORBA::Long)getpid();
176 //=============================================================================
178 * CORBA method: check if servant is still alive
180 //=============================================================================
182 void Engines_Parallel_Container_i::ping()
184 MESSAGE("Engines_Parallel_Container_i::ping() pid "<< getpid());
187 //=============================================================================
189 * CORBA method, oneway: Server shutdown.
190 * - Container name removed from naming service,
191 * - servant deactivation,
192 * - orb shutdown if no other servants in the process
194 //=============================================================================
196 void Engines_Parallel_Container_i::Shutdown()
198 MESSAGE("Engines_Parallel_Container_i::Shutdown()");
199 _NS->Destroy_FullDirectory(_containerName.c_str());
201 //_poa->deactivate_object(*_id);
202 if(_isServantAloneInProcess)
204 MESSAGE("Effective Shutdown of container Begins...");
205 LocalTraceBufferPool* bp1 = LocalTraceBufferPool::instance();
206 bp1->deleteInstance(bp1);
212 //=============================================================================
214 * CORBA method: load a new component class (Python or C++ implementation)
215 * \param componentName like COMPONENT
216 * try to make a Python import of COMPONENT,
217 * then a lib open of libCOMPONENTEngine.so
218 * \return true if dlopen successfull or already done, false otherwise
220 //=============================================================================
223 Engines_Parallel_Container_i::load_component_Library(const char* componentName)
226 string aCompName = componentName;
227 // --- try dlopen C++ component
230 string impl_name = string ("lib") + aCompName + string("Engine.so");
232 string impl_name = aCompName + string("Engine.dll");
237 _numInstanceMutex.lock(); // lock to be alone
238 if (_toRemove_map[impl_name]) _toRemove_map.erase(impl_name);
239 if (_library_map[impl_name])
241 MESSAGE("Library " << impl_name << " already loaded");
242 _numInstanceMutex.unlock();
248 handle = dlopen( impl_name.c_str() , RTLD_LAZY ) ;
250 handle = dlopen( impl_name.c_str() , 0 ) ;
254 _library_map[impl_name] = handle;
255 _numInstanceMutex.unlock();
260 cerr << "Can't load shared library : " << impl_name << endl;
261 cerr << "error dlopen: " << dlerror() << endl;
262 _numInstanceMutex.unlock();
266 // To be sure that all the nodes of the component as loaded the library
267 _my_com->paco_barrier();
272 //=============================================================================
274 * CORBA method: Creates a new servant instance of a component.
275 * The servant registers itself to naming service and Registry.
276 * \param genericRegisterName Name of the component instance to register
277 * in Registry & Name Service (without _inst_n suffix)
278 * \param studyId 0 for multiStudy instance,
279 * study Id (>0) otherwise
280 * \return a loaded component
282 //=============================================================================
284 Engines::Component_ptr
285 Engines_Parallel_Container_i::create_component_instance(const char*genericRegisterName,
288 cerr << "----------------- create_component_instance node : " << getMyRank() << endl;
292 INFOS("studyId must be > 0 for mono study instance, =0 for multiStudy");
293 return Engines::Component::_nil() ;
296 Engines::Component_var iobject = Engines::Component::_nil() ;
298 // is it a parallel component ?
299 bool parallel = false;
300 string aCompName = genericRegisterName;
301 int par = aCompName.find("@PARALLEL@");
304 aCompName = aCompName.substr(0,par);
309 string impl_name = string ("lib") + aCompName +string("Engine.so");
311 string impl_name = aCompName +string("Engine.dll");
313 void* handle = _library_map[impl_name];
317 cerr << "shared library " << impl_name <<"must be loaded before instance" << endl;;
318 return Engines::Component::_nil() ;
323 // Sequential component case
324 // Component parallel proxy created on node 0
325 iobject = createParallelInstance(aCompName,
331 // Sequential component case
332 iobject = createInstance(aCompName,
337 return iobject._retn();
341 //=============================================================================
343 * CORBA method: Finds a servant instance of a component
344 * \param registeredName Name of the component in Registry or Name Service,
345 * without instance suffix number
346 * \param studyId 0 if instance is not associated to a study,
347 * >0 otherwise (== study id)
348 * \return the first instance found with same studyId
350 //=============================================================================
352 Engines::Component_ptr Engines_Parallel_Container_i::find_component_instance( const char* registeredName,
355 Engines::Component_var anEngine = Engines::Component::_nil();
356 map<string,Engines::Component_var>::iterator itm =_listInstances_map.begin();
357 while (itm != _listInstances_map.end())
359 string instance = (*itm).first;
361 if (instance.find(registeredName) == 0)
363 anEngine = (*itm).second;
364 if (studyId == anEngine->getStudyId())
366 return anEngine._retn();
371 return anEngine._retn();
374 //=============================================================================
376 * CORBA method: find or create an instance of the component (servant),
377 * load a new component class (dynamic library) if required,
378 * ---- FOR COMPATIBILITY WITH 2.2 ----
379 * ---- USE ONLY FOR MULTISTUDY INSTANCES ! --------
380 * The servant registers itself to naming service and Registry.
381 * \param genericRegisterName Name of the component to register
382 * in Registry & Name Service
383 * \param componentName Name of the constructed library of the component
384 * \return a loaded component
386 //=============================================================================
388 Engines::Component_ptr Engines_Parallel_Container_i::load_impl( const char* genericRegisterName,
389 const char* componentName )
391 string impl_name = string ("lib") + genericRegisterName +string("Engine.so");
392 Engines::Component_var iobject = Engines::Component::_nil() ;
393 if (load_component_Library(genericRegisterName))
394 iobject = find_or_create_instance(genericRegisterName, impl_name);
395 return iobject._retn();
399 //=============================================================================
401 * CORBA method: Stops the component servant, and deletes all related objects
402 * \param component_i Component to be removed
404 //=============================================================================
406 void Engines_Parallel_Container_i::remove_impl(Engines::Component_ptr component_i)
408 ASSERT(! CORBA::is_nil(component_i));
409 string instanceName = component_i->instanceName() ;
410 MESSAGE("unload component " << instanceName);
411 _listInstances_map.erase(instanceName);
412 component_i->destroy() ;
413 _NS->Destroy_Name(instanceName.c_str());
416 //=============================================================================
418 * CORBA method: Discharges unused libraries from the container.
420 //=============================================================================
422 void Engines_Parallel_Container_i::finalize_removal()
424 MESSAGE("finalize unload : dlclose");
425 _numInstanceMutex.lock(); // lock to be alone
426 // (see decInstanceCnt, load_component_Library)
427 map<string, void *>::iterator ith;
428 for (ith = _toRemove_map.begin(); ith != _toRemove_map.end(); ith++)
430 void *handle = (*ith).second;
431 string impl_name= (*ith).first;
436 // dlclose(handle); // SALOME unstable after ...
437 // _library_map.erase(impl_name);
440 _toRemove_map.clear();
441 _numInstanceMutex.unlock();
444 //=============================================================================
446 * CORBA method: Kill the container process with exit(0).
447 * To remove : never returns !
449 //=============================================================================
451 bool Engines_Parallel_Container_i::Kill_impl()
453 MESSAGE("Engines_Parallel_Container_i::Kill() pid "<< getpid() << " containerName "
454 << _containerName.c_str() << " machineName "
455 << Kernel_Utils::GetHostname().c_str());
456 INFOS("===============================================================");
457 INFOS("= REMOVE calls to Kill_impl in C++ container =");
458 INFOS("===============================================================");
464 //=============================================================================
466 * C++ method: Finds an already existing servant instance of a component, or
467 * create an instance.
468 * ---- USE ONLY FOR MULTISTUDY INSTANCES ! --------
469 * \param genericRegisterName Name of the component instance to register
470 * in Registry & Name Service,
471 * (without _inst_n suffix, like "COMPONENT")
472 * \param componentLibraryName like "libCOMPONENTEngine.so"
473 * \return a loaded component
475 * example with names:
476 * aGenRegisterName = COMPONENT (= first argument)
477 * impl_name = libCOMPONENTEngine.so (= second argument)
478 * _containerName = /Containers/cli76ce/FactoryServer
479 * factoryName = COMPONENTEngine_factory
480 * component_registerBase = /Containers/cli76ce/FactoryServer/COMPONENT
482 * instanceName = COMPONENT_inst_1
483 * component_registerName = /Containers/cli76ce/FactoryServer/COMPONENT_inst_1
485 //=============================================================================
487 Engines::Component_ptr
488 Engines_Parallel_Container_i::find_or_create_instance(string genericRegisterName,
489 string componentLibraryName)
491 string aGenRegisterName = genericRegisterName;
492 string impl_name = componentLibraryName;
493 void* handle = _library_map[impl_name];
496 INFOS("shared library " << impl_name <<"must be loaded before instance");
497 return Engines::Component::_nil() ;
501 // --- find a registered instance in naming service, or create
503 string component_registerBase =
504 _containerName + "/" + aGenRegisterName;
505 Engines::Component_var iobject = Engines::Component::_nil() ;
508 CORBA::Object_var obj =
509 _NS->ResolveFirst( component_registerBase.c_str());
510 if ( CORBA::is_nil( obj ) )
512 iobject = createInstance(genericRegisterName,
514 0); // force multiStudy instance here !
518 iobject = Engines::Component::_narrow( obj ) ;
519 Engines_Component_i *servant =
520 dynamic_cast<Engines_Component_i*>
521 (_poa->reference_to_servant(iobject));
523 int studyId = servant->getStudyId();
524 ASSERT (studyId >= 0);
525 if (studyId == 0) // multiStudy instance, OK
528 MESSAGE(component_registerBase.c_str()<<" already bound");
530 else // monoStudy instance: NOK
532 iobject = Engines::Component::_nil();
533 INFOS("load_impl & find_component_instance methods "
534 << "NOT SUITABLE for mono study components");
540 INFOS( "Container_i::load_impl catched" ) ;
542 return iobject._retn();
546 //=============================================================================
548 * C++ method: create a servant instance of a component.
549 * \param genericRegisterName Name of the component instance to register
550 * in Registry & Name Service,
551 * (without _inst_n suffix, like "COMPONENT")
552 * \param handle loaded library handle
553 * \param studyId 0 for multiStudy instance,
554 * study Id (>0) otherwise
555 * \return a loaded component
557 * example with names:
558 * aGenRegisterName = COMPONENT (= first argument)
559 * _containerName = /Containers/cli76ce/FactoryServer
560 * factoryName = COMPONENTEngine_factory
561 * component_registerBase = /Containers/cli76ce/FactoryServer/COMPONENT
562 * instanceName = COMPONENT_inst_1
563 * component_registerName = /Containers/cli76ce/FactoryServer/COMPONENT_inst_1
565 //=============================================================================
567 Engines::Component_ptr
568 Engines_Parallel_Container_i::createInstance(string genericRegisterName,
572 // --- find the factory
574 string aGenRegisterName = genericRegisterName;
575 string factory_name = aGenRegisterName + string("Engine_factory");
577 SCRUTE(factory_name) ;
579 typedef PortableServer::ObjectId * (*FACTORY_FUNCTION)
581 PortableServer::POA_ptr,
582 PortableServer::ObjectId *,
586 FACTORY_FUNCTION Component_factory
587 = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
590 if ( (error = dlerror() ) != NULL)
592 INFOS("Can't resolve symbol: " + factory_name);
594 return Engines::Component::_nil() ;
597 // --- create instance
598 Engines::Component_var iobject = Engines::Component::_nil() ;
601 _numInstanceMutex.lock() ; // lock on the instance number
603 int numInstance = _numInstance ;
604 _numInstanceMutex.unlock() ;
607 sprintf( aNumI , "%d" , numInstance ) ;
608 string instanceName = aGenRegisterName + "_inst_" + aNumI ;
609 string component_registerName =
610 _containerName + "/" + instanceName;
612 // --- Instanciate required CORBA object
614 PortableServer::ObjectId *id ; //not owner, do not delete (nore use var)
615 id = (Component_factory) ( _orb, _poa, _id, instanceName.c_str(),
616 aGenRegisterName.c_str() ) ;
618 // --- get reference & servant from id
619 CORBA::Object_var obj = _poa->id_to_reference(*id);
620 iobject = Engines::Component::_narrow(obj) ;
622 Engines_Component_i *servant =
623 dynamic_cast<Engines_Component_i*>(_poa->reference_to_servant(iobject));
625 servant->_remove_ref(); // compensate previous id_to_reference
626 _listInstances_map[instanceName] = iobject;
627 _cntInstances_map[aGenRegisterName] += 1;
628 bool ret_studyId = servant->setStudyId(studyId);
631 // --- register the engine under the name
632 // containerName(.dir)/instanceName(.object)
633 _NS->Register(iobject , component_registerName.c_str()) ;
634 MESSAGE( component_registerName.c_str() << " bound" ) ;
638 INFOS( "Container_i::createInstance exception catched" ) ;
640 return iobject._retn();
643 Engines::Component_ptr
644 Engines_Parallel_Container_i::createParallelInstance(string genericRegisterName,
648 cerr << "----------------- createParallelInstance node : " << getMyRank() << endl;
649 // --- create instance
650 Engines::Component_var iobject = Engines::Component::_nil();
651 string aGenRegisterName = genericRegisterName;
653 //////////////////////////////////////////////////////////////////////////
655 // Node 0 create the proxy
656 if (getMyRank() == 0) {
657 // --- find the factory
658 string factory_name = aGenRegisterName + string("EngineProxy_factory");
660 typedef PortableServer::ObjectId * (*FACTORY_FUNCTION)
662 paco_fabrique_thread *,
663 PortableServer::POA_ptr,
664 PortableServer::ObjectId *,
668 FACTORY_FUNCTION Component_factory
669 = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
672 if ( (error = dlerror() ) != NULL) {
673 INFOS("Can't resolve symbol: " + factory_name);
675 return Engines::Component::_nil();
678 _numInstanceMutex.lock() ; // lock on the instance number
680 int numInstance = _numInstance ;
681 _numInstanceMutex.unlock() ;
684 sprintf( aNumI , "%d" , numInstance ) ;
685 string instanceName = aGenRegisterName + "_inst_" + aNumI ;
686 string component_registerName =
687 _containerName + "/" + instanceName;
689 // --- Instanciate required CORBA object
690 PortableServer::ObjectId *id ; //not owner, do not delete (nore use var)
691 id = (Component_factory) ( _orb, new paco_omni_fabrique(), _poa, _id, instanceName.c_str(), getTotalNode()) ;
693 // --- get reference & servant from id
694 CORBA::Object_var obj = _poa->id_to_reference(*id);
695 iobject = Engines::Component::_narrow(obj) ;
697 _listInstances_map[instanceName] = iobject;
698 _cntInstances_map[aGenRegisterName] += 1;
700 // --- register the engine under the name
701 // containerName(.dir)/instanceName(.object)
702 _NS->Register(iobject , component_registerName.c_str()) ;
703 MESSAGE( component_registerName.c_str() << " bound" ) ;
707 INFOS( "Container_i::createParallelInstance exception catched in Proxy creation" ) ;
711 // We have to have the same numIntance to be able to get the proxy reference
712 // in the nameing service.
713 _numInstanceMutex.lock() ; // lock on the instance number
715 // int numInstance = _numInstance ;
716 _numInstanceMutex.unlock() ;
718 cerr << "Node " << getMyRank() << " entering in paco_barrier()" << endl;
719 _my_com->paco_barrier();
720 cerr << "Node " << getMyRank() << " quitting paco_barrier()" << endl;
722 //////////////////////////////////////////////////////////////////////////
726 Engines::Component_PaCO_var iobject2;
729 sprintf( aNumI , "%d" , _numInstance ) ;
730 string instanceName = aGenRegisterName + "_inst_" + aNumI ;
732 string component_registerName = _containerName + "/" + instanceName;
733 string hostname = Kernel_Utils::GetHostname();
735 CORBA::Object_var temp = _NS->Resolve(component_registerName.c_str());
736 Engines::Component_var obj_proxy = Engines::Component::_narrow(temp);
737 proxy_ior = _orb->object_to_string(obj_proxy);
739 // --- find the factory
740 string factory_name = aGenRegisterName + string("Engine_factory");
742 typedef PortableServer::ObjectId * (*FACTORY_FUNCTION)
743 (CORBA::ORB_ptr, char *, int,
744 PortableServer::POA_ptr,
745 PortableServer::ObjectId *,
749 FACTORY_FUNCTION Component_factory
750 = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
753 if ( (error = dlerror() ) != NULL)
755 INFOS("Can't resolve symbol: " + factory_name);
757 return Engines::Component::_nil() ;
762 sprintf(aNumI2 , "%d" , getMyRank()) ;
763 string instanceName = aGenRegisterName + "_inst_node_" + aNumI2;
764 string component_registerName = _containerName + aNumI2 + "/" + instanceName;
766 // --- Instanciate required CORBA object
768 PortableServer::ObjectId *id ; //not owner, do not delete (nore use var)
769 id = (Component_factory) ( _orb, proxy_ior, getMyRank(), _poa, _id, instanceName.c_str(),
770 aGenRegisterName.c_str() ) ;
772 // --- get reference & servant from id
773 CORBA::Object_var obj = _poa->id_to_reference(*id);
774 iobject2 = Engines::Component_PaCO::_narrow(obj) ;
776 // --- register the engine under the name
777 _NS->Register(iobject2 , component_registerName.c_str()) ;
778 MESSAGE( component_registerName.c_str() << " bound" ) ;
782 INFOS( "Container_i::createParallelInstance exception catched" ) ;
785 //////////////////////////////////////////////////////////////////////////
786 // 3: Deployment Step
789 _my_com->paco_barrier();
790 cerr << "--------- createParallelInstance : End Deploy step ----------" << endl;
791 if (getMyRank() == 0) {
792 PaCO::InterfaceManager_var proxy = PaCO::InterfaceManager::_narrow(iobject);
794 _my_com->paco_barrier();
797 _my_com->paco_barrier();
799 return iobject._retn();
802 //=============================================================================
806 //=============================================================================
808 void Engines_Parallel_Container_i::decInstanceCnt(string genericRegisterName)
810 string aGenRegisterName =genericRegisterName;
811 MESSAGE("Engines_Parallel_Container_i::decInstanceCnt " << aGenRegisterName);
812 ASSERT(_cntInstances_map[aGenRegisterName] > 0);
813 _numInstanceMutex.lock(); // lock to be alone
814 // (see finalize_removal, load_component_Library)
815 _cntInstances_map[aGenRegisterName] -= 1;
816 SCRUTE(_cntInstances_map[aGenRegisterName]);
817 if (_cntInstances_map[aGenRegisterName] == 0)
820 Engines_Component_i::GetDynLibraryName(aGenRegisterName.c_str());
822 void* handle = _library_map[impl_name];
824 _toRemove_map[impl_name] = handle;
826 _numInstanceMutex.unlock();
829 //=============================================================================
831 * Retrieves only with container naming convention if it is a python container
833 //=============================================================================
835 bool Engines_Parallel_Container_i::isPythonContainer(const char* ContainerName)
838 int len=strlen(ContainerName);
840 if(strcmp(ContainerName+len-2,"Py")==0)
845 //=============================================================================
849 //=============================================================================
851 void ActSigIntHandler()
854 struct sigaction SigIntAct ;
855 SigIntAct.sa_sigaction = &SigIntHandler ;
856 SigIntAct.sa_flags = SA_SIGINFO ;
859 // DEBUG 03.02.2005 : the first parameter of sigaction is not a mask of signals
860 // (SIGINT | SIGUSR1) :
861 // it must be only one signal ===> one call for SIGINT
862 // and an other one for SIGUSR1
864 if ( sigaction( SIGINT , &SigIntAct, NULL ) ) {
865 perror("SALOME_Container main ") ;
868 if ( sigaction( SIGUSR1 , &SigIntAct, NULL ) ) {
869 perror("SALOME_Container main ") ;
872 //PAL9042 JR : during the execution of a Signal Handler (and of methods called through Signal Handlers)
873 // use of streams (and so on) should never be used because :
874 // streams of C++ are naturally thread-safe and use pthread_mutex_lock ===>
875 // A stream operation may be interrupted by a signal and if the Handler use stream we
876 // may have a "Dead-Lock" ===HangUp
877 //==INFOS is commented
878 // INFOS(pthread_self() << "SigIntHandler activated") ;
880 signal( SIGINT, SigIntHandler );
881 signal( SIGUSR1, SigIntHandler );
889 void SigIntHandler(int what , siginfo_t * siginfo ,
891 //PAL9042 JR : during the execution of a Signal Handler (and of methods called through Signal Handlers)
892 // use of streams (and so on) should never be used because :
893 // streams of C++ are naturally thread-safe and use pthread_mutex_lock ===>
894 // A stream operation may be interrupted by a signal and if the Handler use stream we
895 // may have a "Dead-Lock" ===HangUp
896 //==MESSAGE is commented
897 // MESSAGE(pthread_self() << "SigIntHandler what " << what << endl
898 // << " si_signo " << siginfo->si_signo << endl
899 // << " si_code " << siginfo->si_code << endl
900 // << " si_pid " << siginfo->si_pid) ;
903 // MESSAGE("SigIntHandler END sleeping.") ;
908 if ( siginfo->si_signo == SIGUSR1 ) {
913 // MESSAGE("SigIntHandler BEGIN sleeping.") ;
919 // MESSAGE("SigIntHandler LEAVE sleeping after " << count << " s.") ;
925 void SigIntHandler( int what ) {
926 MESSAGE( pthread_self() << "SigIntHandler what " << what << endl );
929 MESSAGE("SigIntHandler END sleeping.") ;
934 if ( what == SIGUSR1 ) {
939 MESSAGE("SigIntHandler BEGIN sleeping.") ;
945 MESSAGE("SigIntHandler LEAVE sleeping after " << count << " s.") ;
952 //=============================================================================
954 * CORBA method: get or create a fileRef object associated to a local file
955 * (a file on the computer on which runs the container server), which stores
956 * a list of (machine, localFileName) corresponding to copies already done.
958 * \param origFileName absolute path for a local file to copy on other
960 * \return a fileRef object associated to the file.
962 //=============================================================================
965 Engines_Parallel_Container_i::createFileRef(const char* origFileName)
967 string origName(origFileName);
968 Engines::fileRef_var theFileRef = Engines::fileRef::_nil();
970 if (origName[0] != '/')
972 INFOS("path of file to copy must be an absolute path begining with '/'");
973 return Engines::fileRef::_nil();
976 if (CORBA::is_nil(_fileRef_map[origName]))
978 CORBA::Object_var obj=_poa->id_to_reference(*_id);
979 Engines::Container_var pCont = Engines::Container::_narrow(obj);
980 fileRef_i* aFileRef = new fileRef_i(pCont, origFileName);
981 theFileRef = Engines::fileRef::_narrow(aFileRef->_this());
982 _numInstanceMutex.lock() ; // lock to be alone (stl container write)
983 _fileRef_map[origName] = theFileRef;
984 _numInstanceMutex.unlock() ;
987 theFileRef = Engines::fileRef::_duplicate(_fileRef_map[origName]);
988 ASSERT(! CORBA::is_nil(theFileRef));
989 return theFileRef._retn();
992 //=============================================================================
995 * \return a reference to the fileTransfer object
997 //=============================================================================
999 Engines::fileTransfer_ptr
1000 Engines_Parallel_Container_i::getFileTransfer()
1002 Engines::fileTransfer_var aFileTransfer
1003 = Engines::fileTransfer::_duplicate(_fileTransfer);
1004 return aFileTransfer._retn();
1008 Engines::Salome_file_ptr
1009 Engines_Parallel_Container_i::createSalome_file(const char* origFileName)
1011 string origName(origFileName);
1012 if (CORBA::is_nil(_Salome_file_map[origName]))
1014 Salome_file_i* aSalome_file = new Salome_file_i();
1017 aSalome_file->setLocalFile(origFileName);
1018 aSalome_file->recvFiles();
1020 catch (const SALOME::SALOME_Exception& e)
1022 return Engines::Salome_file::_nil();
1025 Engines::Salome_file_var theSalome_file = Engines::Salome_file::_nil();
1026 theSalome_file = Engines::Salome_file::_narrow(aSalome_file->_this());
1027 _numInstanceMutex.lock() ; // lock to be alone (stl container write)
1028 _Salome_file_map[origName] = theSalome_file;
1029 _numInstanceMutex.unlock() ;
1032 Engines::Salome_file_ptr theSalome_file =
1033 Engines::Salome_file::_duplicate(_Salome_file_map[origName]);
1034 ASSERT(!CORBA::is_nil(theSalome_file));
1035 return theSalome_file;
1038 //=============================================================================
1040 * CORBA attribute: Container working directory
1042 //=============================================================================
1045 Engines_Parallel_Container_i::workingdir()
1049 return CORBA::string_dup(wd) ;
1052 //=============================================================================
1054 * CORBA attribute: Container log file name
1056 //=============================================================================
1059 Engines_Parallel_Container_i::logfilename()
1061 return CORBA::string_dup(_logfilename.c_str()) ;
1065 Engines_Parallel_Container_i::logfilename(const char* name)