1 // SALOME_ParallelContainer : implementation of container and engine for ParallelKernel
3 // Copyright (C) 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
22 // File : SALOME_ParallelContainer_i.cxx
23 // Author : Andr� RIBES, EDF
24 // Author : Paul RASCLE, EDF - MARC TAJCHMAN, CEA
26 #include <SALOMEconfig.h>
29 #include <SALOME_Component.hxx>
31 #include "SALOME_ParallelContainer_i.hxx"
33 #include "SALOME_Component_i.hxx"
35 #include "SALOME_FileRef_i.hxx"
36 #include "SALOME_FileTransfer_i.hxx"
37 #include "SALOME_NamingService.hxx"
47 #include "../../adm/win32/SALOME_WNT.hxx"
53 #include "utilities.h"
56 bool _Sleeping = false ;
58 // Containers with name FactoryServer are started via rsh in LifeCycleCORBA
59 // Other Containers are started via start_impl of FactoryServer
61 extern "C" {void ActSigIntHandler() ; }
63 extern "C" {void SigIntHandler(int, siginfo_t *, void *) ; }
65 extern "C" {void SigIntHandler( int ) ; }
69 map<std::string, int> Engines_Parallel_Container_i::_cntInstances_map;
70 map<std::string, void *> Engines_Parallel_Container_i::_library_map;
71 map<std::string, void *> Engines_Parallel_Container_i::_toRemove_map;
72 omni_mutex Engines_Parallel_Container_i::_numInstanceMutex ;
74 //=============================================================================
76 * Default constructor, not for use
78 //=============================================================================
80 Engines_Parallel_Container_i::Engines_Parallel_Container_i (CORBA::ORB_ptr orb, char * ior) :
81 InterfaceParallel_impl(orb,ior), Engines::Container_serv(orb,ior),
86 //=============================================================================
90 //=============================================================================
92 Engines_Parallel_Container_i::Engines_Parallel_Container_i (CORBA::ORB_ptr orb, char * ior,
93 PortableServer::POA_ptr poa,
95 int argc , char* argv[],
97 bool isServantAloneInProcess
99 InterfaceParallel_impl(orb,ior), Engines::Container_serv(orb,ior),
100 _numInstance(0),_isServantAloneInProcess(isServantAloneInProcess)
102 _pid = (long)getpid();
110 string hostname = GetHostname();
112 _orb = CORBA::ORB::_duplicate(orb) ;
113 _poa = PortableServer::POA::_duplicate(poa) ;
114 _NS = new SALOME_NamingService();
115 _NS->init_orb( CORBA::ORB::_duplicate(_orb) );
116 _containerName = _NS->BuildContainerNameForNS(containerName, hostname.c_str());
118 fileTransfer_i* aFileTransfer = new fileTransfer_i();
119 _fileTransfer = Engines::fileTransfer::_narrow(aFileTransfer->_this());
122 //=============================================================================
126 //=============================================================================
128 Engines_Parallel_Container_i::~Engines_Parallel_Container_i()
130 MESSAGE("Container_i::~Container_i()");
134 //=============================================================================
136 * CORBA attribute: Container name (see constructor)
138 //=============================================================================
140 char* Engines_Parallel_Container_i::name()
142 return CORBA::string_dup(_containerName.c_str()) ;
145 //=============================================================================
147 * CORBA method: Get the hostName of the Container (without domain extensions)
149 //=============================================================================
151 char* Engines_Parallel_Container_i::getHostName()
153 string s = GetHostname();
154 MESSAGE("Engines_Parallel_Container_i::getHostName " << s);
155 return CORBA::string_dup(s.c_str()) ;
158 //=============================================================================
160 * CORBA method: Get the PID (process identification) of the Container
162 //=============================================================================
164 CORBA::Long Engines_Parallel_Container_i::getPID()
166 return (CORBA::Long)getpid();
169 //=============================================================================
171 * CORBA method: check if servant is still alive
173 //=============================================================================
175 void Engines_Parallel_Container_i::ping()
177 MESSAGE("Engines_Parallel_Container_i::ping() pid "<< getpid());
180 //=============================================================================
182 * CORBA method, oneway: Server shutdown.
183 * - Container name removed from naming service,
184 * - servant deactivation,
185 * - orb shutdown if no other servants in the process
187 //=============================================================================
189 void Engines_Parallel_Container_i::Shutdown()
191 MESSAGE("Engines_Parallel_Container_i::Shutdown()");
192 _NS->Destroy_FullDirectory(_containerName.c_str());
194 //_poa->deactivate_object(*_id);
195 if(_isServantAloneInProcess)
197 MESSAGE("Effective Shutdown of container Begins...");
198 LocalTraceBufferPool* bp1 = LocalTraceBufferPool::instance();
199 bp1->deleteInstance(bp1);
205 //=============================================================================
207 * CORBA method: load a new component class (Python or C++ implementation)
208 * \param componentName like COMPONENT
209 * try to make a Python import of COMPONENT,
210 * then a lib open of libCOMPONENTEngine.so
211 * \return true if dlopen successfull or already done, false otherwise
213 //=============================================================================
216 Engines_Parallel_Container_i::load_component_Library(const char* componentName)
219 string aCompName = componentName;
220 // --- try dlopen C++ component
223 string impl_name = string ("lib") + aCompName + string("Engine.so");
225 string impl_name = aCompName + string("Engine.dll");
230 _numInstanceMutex.lock(); // lock to be alone
231 if (_toRemove_map[impl_name]) _toRemove_map.erase(impl_name);
232 if (_library_map[impl_name])
234 MESSAGE("Library " << impl_name << " already loaded");
235 _numInstanceMutex.unlock();
241 handle = dlopen( impl_name.c_str() , RTLD_LAZY ) ;
243 handle = dlopen( impl_name.c_str() , 0 ) ;
247 _library_map[impl_name] = handle;
248 _numInstanceMutex.unlock();
253 cerr << "Can't load shared library : " << impl_name << endl;
254 cerr << "error dlopen: " << dlerror() << endl;
255 _numInstanceMutex.unlock();
259 // To be sure that all the nodes of the component as loaded the library
260 global_paco_context_ptr->my_com->paco_barrier();
265 //=============================================================================
267 * CORBA method: Creates a new servant instance of a component.
268 * The servant registers itself to naming service and Registry.
269 * \param genericRegisterName Name of the component instance to register
270 * in Registry & Name Service (without _inst_n suffix)
271 * \param studyId 0 for multiStudy instance,
272 * study Id (>0) otherwise
273 * \return a loaded component
275 //=============================================================================
277 Engines::Component_ptr
278 Engines_Parallel_Container_i::create_component_instance(const char*genericRegisterName,
281 cerr << "----------------- create_component_instance node : " << getMyRank() << endl;
285 INFOS("studyId must be > 0 for mono study instance, =0 for multiStudy");
286 return Engines::Component::_nil() ;
289 Engines::Component_var iobject = Engines::Component::_nil() ;
291 // is it a parallel component ?
292 bool parallel = false;
293 string aCompName = genericRegisterName;
294 int par = aCompName.find("@PARALLEL@");
297 aCompName = aCompName.substr(0,par);
302 string impl_name = string ("lib") + aCompName +string("Engine.so");
304 string impl_name = aCompName +string("Engine.dll");
306 void* handle = _library_map[impl_name];
310 cerr << "shared library " << impl_name <<"must be loaded before instance" << endl;;
311 return Engines::Component::_nil() ;
316 // Sequential component case
317 // Component parallel proxy created on node 0
318 iobject = createParallelInstance(aCompName,
324 // Sequential component case
325 iobject = createInstance(aCompName,
330 return iobject._retn();
334 //=============================================================================
336 * CORBA method: Finds a servant instance of a component
337 * \param registeredName Name of the component in Registry or Name Service,
338 * without instance suffix number
339 * \param studyId 0 if instance is not associated to a study,
340 * >0 otherwise (== study id)
341 * \return the first instance found with same studyId
343 //=============================================================================
345 Engines::Component_ptr Engines_Parallel_Container_i::find_component_instance( const char* registeredName,
348 Engines::Component_var anEngine = Engines::Component::_nil();
349 map<string,Engines::Component_var>::iterator itm =_listInstances_map.begin();
350 while (itm != _listInstances_map.end())
352 string instance = (*itm).first;
354 if (instance.find(registeredName) == 0)
356 anEngine = (*itm).second;
357 if (studyId == anEngine->getStudyId())
359 return anEngine._retn();
364 return anEngine._retn();
367 //=============================================================================
369 * CORBA method: find or create an instance of the component (servant),
370 * load a new component class (dynamic library) if required,
371 * ---- FOR COMPATIBILITY WITH 2.2 ----
372 * ---- USE ONLY FOR MULTISTUDY INSTANCES ! --------
373 * The servant registers itself to naming service and Registry.
374 * \param genericRegisterName Name of the component to register
375 * in Registry & Name Service
376 * \param componentName Name of the constructed library of the component
377 * \return a loaded component
379 //=============================================================================
381 Engines::Component_ptr Engines_Parallel_Container_i::load_impl( const char* genericRegisterName,
382 const char* componentName )
384 string impl_name = string ("lib") + genericRegisterName +string("Engine.so");
385 Engines::Component_var iobject = Engines::Component::_nil() ;
386 if (load_component_Library(genericRegisterName))
387 iobject = find_or_create_instance(genericRegisterName, impl_name);
388 return iobject._retn();
392 //=============================================================================
394 * CORBA method: Stops the component servant, and deletes all related objects
395 * \param component_i Component to be removed
397 //=============================================================================
399 void Engines_Parallel_Container_i::remove_impl(Engines::Component_ptr component_i)
401 ASSERT(! CORBA::is_nil(component_i));
402 string instanceName = component_i->instanceName() ;
403 MESSAGE("unload component " << instanceName);
404 _listInstances_map.erase(instanceName);
405 component_i->destroy() ;
406 _NS->Destroy_Name(instanceName.c_str());
409 //=============================================================================
411 * CORBA method: Discharges unused libraries from the container.
413 //=============================================================================
415 void Engines_Parallel_Container_i::finalize_removal()
417 MESSAGE("finalize unload : dlclose");
418 _numInstanceMutex.lock(); // lock to be alone
419 // (see decInstanceCnt, load_component_Library)
420 map<string, void *>::iterator ith;
421 for (ith = _toRemove_map.begin(); ith != _toRemove_map.end(); ith++)
423 void *handle = (*ith).second;
424 string impl_name= (*ith).first;
429 // dlclose(handle); // SALOME unstable after ...
430 // _library_map.erase(impl_name);
433 _toRemove_map.clear();
434 _numInstanceMutex.unlock();
437 //=============================================================================
439 * CORBA method: Kill the container process with exit(0).
440 * To remove : never returns !
442 //=============================================================================
444 bool Engines_Parallel_Container_i::Kill_impl()
446 MESSAGE("Engines_Parallel_Container_i::Kill() pid "<< getpid() << " containerName "
447 << _containerName.c_str() << " machineName "
448 << GetHostname().c_str());
449 INFOS("===============================================================");
450 INFOS("= REMOVE calls to Kill_impl in C++ container =");
451 INFOS("===============================================================");
457 //=============================================================================
459 * C++ method: Finds an already existing servant instance of a component, or
460 * create an instance.
461 * ---- USE ONLY FOR MULTISTUDY INSTANCES ! --------
462 * \param genericRegisterName Name of the component instance to register
463 * in Registry & Name Service,
464 * (without _inst_n suffix, like "COMPONENT")
465 * \param componentLibraryName like "libCOMPONENTEngine.so"
466 * \return a loaded component
468 * example with names:
469 * aGenRegisterName = COMPONENT (= first argument)
470 * impl_name = libCOMPONENTEngine.so (= second argument)
471 * _containerName = /Containers/cli76ce/FactoryServer
472 * factoryName = COMPONENTEngine_factory
473 * component_registerBase = /Containers/cli76ce/FactoryServer/COMPONENT
475 * instanceName = COMPONENT_inst_1
476 * component_registerName = /Containers/cli76ce/FactoryServer/COMPONENT_inst_1
478 //=============================================================================
480 Engines::Component_ptr
481 Engines_Parallel_Container_i::find_or_create_instance(string genericRegisterName,
482 string componentLibraryName)
484 string aGenRegisterName = genericRegisterName;
485 string impl_name = componentLibraryName;
486 void* handle = _library_map[impl_name];
489 INFOS("shared library " << impl_name <<"must be loaded before instance");
490 return Engines::Component::_nil() ;
494 // --- find a registered instance in naming service, or create
496 string component_registerBase =
497 _containerName + "/" + aGenRegisterName;
498 Engines::Component_var iobject = Engines::Component::_nil() ;
501 CORBA::Object_var obj =
502 _NS->ResolveFirst( component_registerBase.c_str());
503 if ( CORBA::is_nil( obj ) )
505 iobject = createInstance(genericRegisterName,
507 0); // force multiStudy instance here !
511 iobject = Engines::Component::_narrow( obj ) ;
512 Engines_Component_i *servant =
513 dynamic_cast<Engines_Component_i*>
514 (_poa->reference_to_servant(iobject));
516 int studyId = servant->getStudyId();
517 ASSERT (studyId >= 0);
518 if (studyId == 0) // multiStudy instance, OK
521 MESSAGE(component_registerBase.c_str()<<" already bound");
523 else // monoStudy instance: NOK
525 iobject = Engines::Component::_nil();
526 INFOS("load_impl & find_component_instance methods "
527 << "NOT SUITABLE for mono study components");
533 INFOS( "Container_i::load_impl catched" ) ;
535 return iobject._retn();
539 //=============================================================================
541 * C++ method: create a servant instance of a component.
542 * \param genericRegisterName Name of the component instance to register
543 * in Registry & Name Service,
544 * (without _inst_n suffix, like "COMPONENT")
545 * \param handle loaded library handle
546 * \param studyId 0 for multiStudy instance,
547 * study Id (>0) otherwise
548 * \return a loaded component
550 * example with names:
551 * aGenRegisterName = COMPONENT (= first argument)
552 * _containerName = /Containers/cli76ce/FactoryServer
553 * factoryName = COMPONENTEngine_factory
554 * component_registerBase = /Containers/cli76ce/FactoryServer/COMPONENT
555 * instanceName = COMPONENT_inst_1
556 * component_registerName = /Containers/cli76ce/FactoryServer/COMPONENT_inst_1
558 //=============================================================================
560 Engines::Component_ptr
561 Engines_Parallel_Container_i::createInstance(string genericRegisterName,
565 // --- find the factory
567 string aGenRegisterName = genericRegisterName;
568 string factory_name = aGenRegisterName + string("Engine_factory");
570 SCRUTE(factory_name) ;
572 typedef PortableServer::ObjectId * (*FACTORY_FUNCTION)
574 PortableServer::POA_ptr,
575 PortableServer::ObjectId *,
579 FACTORY_FUNCTION Component_factory
580 = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
583 if ( (error = dlerror() ) != NULL)
585 INFOS("Can't resolve symbol: " + factory_name);
587 return Engines::Component::_nil() ;
590 // --- create instance
591 Engines::Component_var iobject = Engines::Component::_nil() ;
594 _numInstanceMutex.lock() ; // lock on the instance number
596 int numInstance = _numInstance ;
597 _numInstanceMutex.unlock() ;
600 sprintf( aNumI , "%d" , numInstance ) ;
601 string instanceName = aGenRegisterName + "_inst_" + aNumI ;
602 string component_registerName =
603 _containerName + "/" + instanceName;
605 // --- Instanciate required CORBA object
607 PortableServer::ObjectId *id ; //not owner, do not delete (nore use var)
608 id = (Component_factory) ( _orb, _poa, _id, instanceName.c_str(),
609 aGenRegisterName.c_str() ) ;
611 // --- get reference & servant from id
612 CORBA::Object_var obj = _poa->id_to_reference(*id);
613 iobject = Engines::Component::_narrow(obj) ;
615 Engines_Component_i *servant =
616 dynamic_cast<Engines_Component_i*>(_poa->reference_to_servant(iobject));
618 servant->_remove_ref(); // compensate previous id_to_reference
619 _listInstances_map[instanceName] = iobject;
620 _cntInstances_map[aGenRegisterName] += 1;
621 bool ret_studyId = servant->setStudyId(studyId);
624 // --- register the engine under the name
625 // containerName(.dir)/instanceName(.object)
626 _NS->Register(iobject , component_registerName.c_str()) ;
627 MESSAGE( component_registerName.c_str() << " bound" ) ;
631 INFOS( "Container_i::createInstance exception catched" ) ;
633 return iobject._retn();
636 Engines::Component_ptr
637 Engines_Parallel_Container_i::createParallelInstance(string genericRegisterName,
641 cerr << "----------------- createParallelInstance node : " << getMyRank() << endl;
642 // --- create instance
643 Engines::Component_var iobject = Engines::Component::_nil();
644 string aGenRegisterName = genericRegisterName;
646 //////////////////////////////////////////////////////////////////////////
648 // Node 0 create the proxy
649 if (getMyRank() == 0) {
650 // --- find the factory
651 string factory_name = aGenRegisterName + string("EngineProxy_factory");
653 typedef PortableServer::ObjectId * (*FACTORY_FUNCTION)
655 PortableServer::POA_ptr,
656 PortableServer::ObjectId *,
660 FACTORY_FUNCTION Component_factory
661 = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
664 if ( (error = dlerror() ) != NULL) {
665 INFOS("Can't resolve symbol: " + factory_name);
667 return Engines::Component::_nil();
670 _numInstanceMutex.lock() ; // lock on the instance number
672 int numInstance = _numInstance ;
673 _numInstanceMutex.unlock() ;
676 sprintf( aNumI , "%d" , numInstance ) ;
677 string instanceName = aGenRegisterName + "_inst_" + aNumI ;
678 string component_registerName =
679 _containerName + "/" + instanceName;
681 // --- Instanciate required CORBA object
682 PortableServer::ObjectId *id ; //not owner, do not delete (nore use var)
683 id = (Component_factory) ( _orb, _poa, _id, instanceName.c_str(), getTotalNode()) ;
685 // --- get reference & servant from id
686 CORBA::Object_var obj = _poa->id_to_reference(*id);
687 iobject = Engines::Component::_narrow(obj) ;
689 _listInstances_map[instanceName] = iobject;
690 _cntInstances_map[aGenRegisterName] += 1;
692 // --- register the engine under the name
693 // containerName(.dir)/instanceName(.object)
694 _NS->Register(iobject , component_registerName.c_str()) ;
695 MESSAGE( component_registerName.c_str() << " bound" ) ;
699 INFOS( "Container_i::createParallelInstance exception catched in Proxy creation" ) ;
703 // We have to have the same numIntance to be able to get the proxy reference
704 // in the nameing service.
705 _numInstanceMutex.lock() ; // lock on the instance number
707 // int numInstance = _numInstance ;
708 _numInstanceMutex.unlock() ;
710 cerr << "Node " << getMyRank() << " entering in paco_barrier()" << endl;
711 global_paco_context_ptr->my_com->paco_barrier();
712 cerr << "Node " << getMyRank() << " quitting paco_barrier()" << endl;
714 //////////////////////////////////////////////////////////////////////////
718 Engines::Component_PaCO_var iobject2;
721 sprintf( aNumI , "%d" , _numInstance ) ;
722 string instanceName = aGenRegisterName + "_inst_" + aNumI ;
724 string component_registerName = _containerName + "/" + instanceName;
725 string hostname = GetHostname();
727 CORBA::Object_var temp = _NS->Resolve(component_registerName.c_str());
728 Engines::Component_var obj_proxy = Engines::Component::_narrow(temp);
729 proxy_ior = _orb->object_to_string(obj_proxy);
731 // --- find the factory
732 string factory_name = aGenRegisterName + string("Engine_factory");
734 typedef PortableServer::ObjectId * (*FACTORY_FUNCTION)
735 (CORBA::ORB_ptr, char * ior,
736 PortableServer::POA_ptr,
737 PortableServer::ObjectId *,
741 FACTORY_FUNCTION Component_factory
742 = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
745 if ( (error = dlerror() ) != NULL)
747 INFOS("Can't resolve symbol: " + factory_name);
749 return Engines::Component::_nil() ;
754 sprintf(aNumI2 , "%d" , getMyRank()) ;
755 string instanceName = aGenRegisterName + "_inst_node_" + aNumI2;
756 string component_registerName = _containerName + aNumI2 + "/" + instanceName;
758 // --- Instanciate required CORBA object
760 PortableServer::ObjectId *id ; //not owner, do not delete (nore use var)
761 id = (Component_factory) ( _orb, proxy_ior, _poa, _id, instanceName.c_str(),
762 aGenRegisterName.c_str() ) ;
764 // --- get reference & servant from id
765 CORBA::Object_var obj = _poa->id_to_reference(*id);
766 iobject2 = Engines::Component_PaCO::_narrow(obj) ;
768 // --- register the engine under the name
769 _NS->Register(iobject2 , component_registerName.c_str()) ;
770 MESSAGE( component_registerName.c_str() << " bound" ) ;
774 INFOS( "Container_i::createParallelInstance exception catched" ) ;
777 //////////////////////////////////////////////////////////////////////////
778 // 3: Deployment Step
780 iobject2->deploy(getMyRank());
781 global_paco_context_ptr->my_com->paco_barrier();
782 cerr << "--------- createParallelInstance : End Deploy step ----------" << endl;
784 // return obj_proxy._retn();
785 return iobject._retn();
788 //=============================================================================
792 //=============================================================================
794 void Engines_Parallel_Container_i::decInstanceCnt(string genericRegisterName)
796 string aGenRegisterName =genericRegisterName;
797 MESSAGE("Engines_Parallel_Container_i::decInstanceCnt " << aGenRegisterName);
798 ASSERT(_cntInstances_map[aGenRegisterName] > 0);
799 _numInstanceMutex.lock(); // lock to be alone
800 // (see finalize_removal, load_component_Library)
801 _cntInstances_map[aGenRegisterName] -= 1;
802 SCRUTE(_cntInstances_map[aGenRegisterName]);
803 if (_cntInstances_map[aGenRegisterName] == 0)
806 Engines_Component_i::GetDynLibraryName(aGenRegisterName.c_str());
808 void* handle = _library_map[impl_name];
810 _toRemove_map[impl_name] = handle;
812 _numInstanceMutex.unlock();
815 //=============================================================================
817 * Retrieves only with container naming convention if it is a python container
819 //=============================================================================
821 bool Engines_Parallel_Container_i::isPythonContainer(const char* ContainerName)
824 int len=strlen(ContainerName);
826 if(strcmp(ContainerName+len-2,"Py")==0)
831 //=============================================================================
835 //=============================================================================
837 void ActSigIntHandler()
840 struct sigaction SigIntAct ;
841 SigIntAct.sa_sigaction = &SigIntHandler ;
842 SigIntAct.sa_flags = SA_SIGINFO ;
845 // DEBUG 03.02.2005 : the first parameter of sigaction is not a mask of signals
846 // (SIGINT | SIGUSR1) :
847 // it must be only one signal ===> one call for SIGINT
848 // and an other one for SIGUSR1
850 if ( sigaction( SIGINT , &SigIntAct, NULL ) ) {
851 perror("SALOME_Container main ") ;
854 if ( sigaction( SIGUSR1 , &SigIntAct, NULL ) ) {
855 perror("SALOME_Container main ") ;
858 //PAL9042 JR : during the execution of a Signal Handler (and of methods called through Signal Handlers)
859 // use of streams (and so on) should never be used because :
860 // streams of C++ are naturally thread-safe and use pthread_mutex_lock ===>
861 // A stream operation may be interrupted by a signal and if the Handler use stream we
862 // may have a "Dead-Lock" ===HangUp
863 //==INFOS is commented
864 // INFOS(pthread_self() << "SigIntHandler activated") ;
866 signal( SIGINT, SigIntHandler );
867 signal( SIGUSR1, SigIntHandler );
875 void SigIntHandler(int what , siginfo_t * siginfo ,
877 //PAL9042 JR : during the execution of a Signal Handler (and of methods called through Signal Handlers)
878 // use of streams (and so on) should never be used because :
879 // streams of C++ are naturally thread-safe and use pthread_mutex_lock ===>
880 // A stream operation may be interrupted by a signal and if the Handler use stream we
881 // may have a "Dead-Lock" ===HangUp
882 //==MESSAGE is commented
883 // MESSAGE(pthread_self() << "SigIntHandler what " << what << endl
884 // << " si_signo " << siginfo->si_signo << endl
885 // << " si_code " << siginfo->si_code << endl
886 // << " si_pid " << siginfo->si_pid) ;
889 // MESSAGE("SigIntHandler END sleeping.") ;
894 if ( siginfo->si_signo == SIGUSR1 ) {
899 // MESSAGE("SigIntHandler BEGIN sleeping.") ;
905 // MESSAGE("SigIntHandler LEAVE sleeping after " << count << " s.") ;
911 void SigIntHandler( int what ) {
912 MESSAGE( pthread_self() << "SigIntHandler what " << what << endl );
915 MESSAGE("SigIntHandler END sleeping.") ;
920 if ( what == SIGUSR1 ) {
925 MESSAGE("SigIntHandler BEGIN sleeping.") ;
931 MESSAGE("SigIntHandler LEAVE sleeping after " << count << " s.") ;
938 //=============================================================================
940 * CORBA method: get or create a fileRef object associated to a local file
941 * (a file on the computer on which runs the container server), which stores
942 * a list of (machine, localFileName) corresponding to copies already done.
944 * \param origFileName absolute path for a local file to copy on other
946 * \return a fileRef object associated to the file.
948 //=============================================================================
951 Engines_Parallel_Container_i::createFileRef(const char* origFileName)
953 string origName(origFileName);
954 Engines::fileRef_var theFileRef = Engines::fileRef::_nil();
956 if (origName[0] != '/')
958 INFOS("path of file to copy must be an absolute path begining with '/'");
959 return Engines::fileRef::_nil();
962 if (CORBA::is_nil(_fileRef_map[origName]))
964 CORBA::Object_var obj=_poa->id_to_reference(*_id);
965 Engines::Container_var pCont = Engines::Container::_narrow(obj);
966 fileRef_i* aFileRef = new fileRef_i(pCont, origFileName);
967 theFileRef = Engines::fileRef::_narrow(aFileRef->_this());
968 _numInstanceMutex.lock() ; // lock to be alone (stl container write)
969 _fileRef_map[origName] = theFileRef;
970 _numInstanceMutex.unlock() ;
973 theFileRef = Engines::fileRef::_duplicate(_fileRef_map[origName]);
974 ASSERT(! CORBA::is_nil(theFileRef));
975 return theFileRef._retn();
978 //=============================================================================
981 * \return a reference to the fileTransfer object
983 //=============================================================================
985 Engines::fileTransfer_ptr
986 Engines_Parallel_Container_i::getFileTransfer()
988 Engines::fileTransfer_var aFileTransfer
989 = Engines::fileTransfer::_duplicate(_fileTransfer);
990 return aFileTransfer._retn();
994 Engines::Salome_file_ptr
995 Engines_Parallel_Container_i::createSalome_file(const char* origFileName)
997 string origName(origFileName);
998 if (CORBA::is_nil(_Salome_file_map[origName]))
1000 Salome_file_i* aSalome_file = new Salome_file_i();
1003 aSalome_file->setLocalFile(origFileName);
1004 aSalome_file->recvFiles();
1006 catch (const SALOME::SALOME_Exception& e)
1008 return Engines::Salome_file::_nil();
1011 Engines::Salome_file_var theSalome_file = Engines::Salome_file::_nil();
1012 theSalome_file = Engines::Salome_file::_narrow(aSalome_file->_this());
1013 _numInstanceMutex.lock() ; // lock to be alone (stl container write)
1014 _Salome_file_map[origName] = theSalome_file;
1015 _numInstanceMutex.unlock() ;
1018 Engines::Salome_file_ptr theSalome_file =
1019 Engines::Salome_file::_duplicate(_Salome_file_map[origName]);
1020 ASSERT(!CORBA::is_nil(theSalome_file));
1021 return theSalome_file;