X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FParallelContainer%2FSALOME_ParallelContainer_i.cxx;h=63ee3a7aca9c81d92aeb44c5f578be8dacdfd21c;hb=d8edd4804d9e6513a17c497c1a30326d4ba0d677;hp=52f5e70704c5459bf8dd69ee1945299fb587b894;hpb=7d2fe213bdf5bf962ce11e253020c9d3e0bc1cce;p=modules%2Fkernel.git diff --git a/src/ParallelContainer/SALOME_ParallelContainer_i.cxx b/src/ParallelContainer/SALOME_ParallelContainer_i.cxx index 52f5e7070..63ee3a7ac 100644 --- a/src/ParallelContainer/SALOME_ParallelContainer_i.cxx +++ b/src/ParallelContainer/SALOME_ParallelContainer_i.cxx @@ -1,63 +1,56 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SALOME_ParallelContainer : implementation of container and engine for ParallelKernel // File : SALOME_ParallelContainer_i.cxx -// Author : Andr� RIBES, EDF -// Author : Paul RASCLE, EDF - MARC TAJCHMAN, CEA -// -#include -#ifndef WIN32 -#else -#include -#endif -#include "SALOME_ParallelContainer_i.hxx" +// Author : André RIBES, EDF +#include "SALOME_ParallelContainer_i.hxx" #include "SALOME_Component_i.hxx" - #include "SALOME_FileRef_i.hxx" #include "SALOME_FileTransfer_i.hxx" #include "SALOME_NamingService.hxx" #include "OpUtil.hxx" +#include "utilities.h" +#include "Basics_Utils.hxx" #include #include #ifndef WIN32 +#include #include #include #else -#include "../../adm/win32/SALOME_WNT.hxx" #include #include +#include int SIGUSR1 = 1000; #endif #include -#include "utilities.h" -using namespace std; -bool _Sleeping = false ; +#include +#include "Container_init_python.hxx" -// Containers with name FactoryServer are started via rsh in LifeCycleCORBA -// Other Containers are started via start_impl of FactoryServer + +bool _Sleeping = false ; extern "C" {void ActSigIntHandler() ; } #ifndef WIN32 @@ -66,64 +59,69 @@ extern "C" {void SigIntHandler(int, siginfo_t *, void *) ; } extern "C" {void SigIntHandler( int ) ; } #endif - -map Engines_Parallel_Container_i::_cntInstances_map; -map Engines_Parallel_Container_i::_library_map; -map Engines_Parallel_Container_i::_toRemove_map; -omni_mutex Engines_Parallel_Container_i::_numInstanceMutex ; - -//============================================================================= -/*! - * Default constructor, not for use +/*! \class Engines_Parallel_Container_i + * \brief C++ implementation of Engines::Container interface for parallel + * container implemented with PaCO++ */ -//============================================================================= - -Engines_Parallel_Container_i::Engines_Parallel_Container_i (CORBA::ORB_ptr orb, - char * ior, - int rank) : - InterfaceParallel_impl(orb,ior,rank), - Engines::Container_serv(orb,ior,rank), - _numInstance(0) -{ -} //============================================================================= /*! - * Construtor to use + * Constructor */ //============================================================================= Engines_Parallel_Container_i::Engines_Parallel_Container_i (CORBA::ORB_ptr orb, - char * ior, - int rank, - PortableServer::POA_ptr poa, - char *containerName , - int argc , char* argv[], - bool activAndRegist, - bool isServantAloneInProcess - ) : + char * ior, + int rank, + PortableServer::POA_ptr poa, + std::string containerName, + bool isServantAloneInProcess) : InterfaceParallel_impl(orb,ior,rank), + Engines::PACO_Container_serv(orb,ior,rank), + Engines::PACO_Container_base_serv(orb,ior,rank), Engines::Container_serv(orb,ior,rank), + Engines::Container_base_serv(orb,ior,rank), _numInstance(0),_isServantAloneInProcess(isServantAloneInProcess) { - _pid = (long)getpid(); - - if(activAndRegist) - ActSigIntHandler() ; - - _argc = argc ; - _argv = argv ; - - string hostname = Kernel_Utils::GetHostname(); - - _orb = CORBA::ORB::_duplicate(orb) ; - _poa = PortableServer::POA::_duplicate(poa) ; + // Members init + _pid = getpid(); + _hostname = Kernel_Utils::GetHostname(); + _orb = CORBA::ORB::_duplicate(orb); + _poa = PortableServer::POA::_duplicate(poa); + + // Add CORBA object to the poa + _id = _poa->activate_object(this); + this->_remove_ref(); + CORBA::Object_var container_node = _poa->id_to_reference(*_id); + + // Adding this servant to SALOME _NS = new SALOME_NamingService(); - _NS->init_orb( CORBA::ORB::_duplicate(_orb) ); - _containerName = _NS->BuildContainerNameForNS(containerName, hostname.c_str()); - + _NS->init_orb(_orb); + _containerName = _NS->BuildContainerNameForNS(containerName.c_str(), _hostname.c_str()); + + // Ajout du numero de noeud + char node_number[12]; + sprintf(node_number, "%d", getMyRank()); + _containerName = _containerName + node_number; + + // Init Python container part + CORBA::String_var sior = _orb->object_to_string(container_node); + std::string myCommand="pyCont = SALOME_Container.SALOME_Container_i('"; + myCommand += _containerName + "','"; + myCommand += sior; + myCommand += "')\n"; + Py_ACQUIRE_NEW_THREAD; + PyRun_SimpleString("import SALOME_Container\n"); + PyRun_SimpleString((char*)myCommand.c_str()); + Py_RELEASE_NEW_THREAD; + + // Init FileTransfer service fileTransfer_i* aFileTransfer = new fileTransfer_i(); - _fileTransfer = Engines::fileTransfer::_narrow(aFileTransfer->_this()); + _fileTransfer = aFileTransfer->_this(); + aFileTransfer->_remove_ref(); + + // Some signal handlers + ActSigIntHandler(); } //============================================================================= @@ -135,10 +133,14 @@ Engines_Parallel_Container_i::Engines_Parallel_Container_i (CORBA::ORB_ptr orb, Engines_Parallel_Container_i::~Engines_Parallel_Container_i() { MESSAGE("Container_i::~Container_i()"); - delete _id; + if (_id) + delete _id; + if(_NS) + delete _NS; } //============================================================================= +//! Get container name /*! * CORBA attribute: Container name (see constructor) */ @@ -150,6 +152,42 @@ char* Engines_Parallel_Container_i::name() } //============================================================================= +//! Get container working directory +/*! + * CORBA attribute: Container working directory + */ +//============================================================================= + +char* +Engines_Parallel_Container_i::workingdir() +{ + char wd[256]; + getcwd (wd,256); + return CORBA::string_dup(wd) ; +} + +//============================================================================= +//! Get container log file name +/*! + * CORBA attribute: Container log file name + */ +//============================================================================= + +char* +Engines_Parallel_Container_i::logfilename() +{ + return CORBA::string_dup(_logfilename.c_str()) ; +} + +//! Set container log file name +void +Engines_Parallel_Container_i::logfilename(const char* name) +{ + _logfilename=name; +} + +//============================================================================= +//! Get container host name /*! * CORBA method: Get the hostName of the Container (without domain extensions) */ @@ -157,12 +195,12 @@ char* Engines_Parallel_Container_i::name() char* Engines_Parallel_Container_i::getHostName() { - string s = Kernel_Utils::GetHostname(); - MESSAGE("Engines_Parallel_Container_i::getHostName " << s); - return CORBA::string_dup(s.c_str()) ; + MESSAGE("Warning: getHostName of a parallel container returns the hostname of the first servant node"); + return CORBA::string_dup(_hostname.c_str()) ; } //============================================================================= +//! Get container PID /*! * CORBA method: Get the PID (process identification) of the Container */ @@ -170,10 +208,12 @@ char* Engines_Parallel_Container_i::getHostName() CORBA::Long Engines_Parallel_Container_i::getPID() { - return (CORBA::Long)getpid(); + MESSAGE("Warning: getPID of a parallel container returns the PID of the first servant node"); + return _pid; } //============================================================================= +//! Ping the servant to check it is still alive /*! * CORBA method: check if servant is still alive */ @@ -181,10 +221,11 @@ CORBA::Long Engines_Parallel_Container_i::getPID() void Engines_Parallel_Container_i::ping() { - MESSAGE("Engines_Parallel_Container_i::ping() pid "<< getpid()); + MESSAGE("Engines_Parallel_Container_i::ping() my pid is "<< _pid); } //============================================================================= +//! Shutdown the container /*! * CORBA method, oneway: Server shutdown. * - Container name removed from naming service, @@ -196,182 +237,259 @@ void Engines_Parallel_Container_i::ping() void Engines_Parallel_Container_i::Shutdown() { MESSAGE("Engines_Parallel_Container_i::Shutdown()"); + + /* For each seq component contained in this container + * tell it to self-destroy + */ + std::map::iterator itm; + for (itm = _listInstances_map.begin(); itm != _listInstances_map.end(); itm++) + { + try + { + itm->second->destroy(); + } + catch(const CORBA::Exception& e) + { + // ignore this entry and continue + } + catch(...) + { + // ignore this entry and continue + } + } + + // Destroy each parallel component node... + std::map::iterator i; + for (i = _par_obj_inst_map.begin(); i != _par_obj_inst_map.end(); i++) + _poa->deactivate_object(*(i->second)); + _NS->Destroy_FullDirectory(_containerName.c_str()); - //_remove_ref(); - //_poa->deactivate_object(*_id); + _NS->Destroy_Name(_containerName.c_str()); + if(_isServantAloneInProcess) { MESSAGE("Effective Shutdown of container Begins..."); - LocalTraceBufferPool* bp1 = LocalTraceBufferPool::instance(); - bp1->deleteInstance(bp1); - _orb->shutdown(0); + if(!CORBA::is_nil(_orb)) + _orb->shutdown(0); } } //============================================================================= +//! load a new component class /*! * CORBA method: load a new component class (Python or C++ implementation) * \param componentName like COMPONENT * try to make a Python import of COMPONENT, * then a lib open of libCOMPONENTEngine.so - * \return true if dlopen successfull or already done, false otherwise + * \return true if dlopen successful or already done, false otherwise */ //============================================================================= bool -Engines_Parallel_Container_i::load_component_Library(const char* componentName) +Engines_Parallel_Container_i::load_component_Library(const char* componentName, CORBA::String_out reason) { - bool ret = false; - string aCompName = componentName; - // --- try dlopen C++ component + reason=CORBA::string_dup(""); + MESSAGE("Begin of load_component_Library : " << componentName) + bool ret = false; + std::string aCompName = componentName; #ifndef WIN32 - string impl_name = string ("lib") + aCompName + string("Engine.so"); +#ifdef __APPLE__ + std::string impl_name = string ("lib") + aCompName + string("Engine.dylib"); #else - string impl_name = aCompName + string("Engine.dll"); + std::string impl_name = string ("lib") + aCompName + string("Engine.so"); +#endif +#else + std::string impl_name = aCompName + string("Engine.dll"); #endif - - SCRUTE(impl_name); _numInstanceMutex.lock(); // lock to be alone - if (_toRemove_map[impl_name]) _toRemove_map.erase(impl_name); - if (_library_map[impl_name]) + + // Check if already loaded or imported in the container + if (_toRemove_map.count(impl_name) != 0) _toRemove_map.erase(impl_name); + if (_library_map.count(impl_name) != 0) { MESSAGE("Library " << impl_name << " already loaded"); - _numInstanceMutex.unlock(); + ret = true; + } + if (_library_map.count(aCompName) != 0) + { + MESSAGE("Python component already imported"); ret = true; } - void* handle; + // --- try dlopen C++ component + if (!ret) + { + MESSAGE("Try to load C++ component"); + void* handle; #ifndef WIN32 - handle = dlopen( impl_name.c_str() , RTLD_LAZY ) ; + handle = dlopen( impl_name.c_str() , RTLD_LAZY | RTLD_GLOBAL ) ; #else - handle = dlopen( impl_name.c_str() , 0 ) ; + handle = dlopen( impl_name.c_str() , 0 ) ; #endif - if ( handle ) - { - _library_map[impl_name] = handle; - _numInstanceMutex.unlock(); - ret = true; + if ( handle ) + { + _library_map[impl_name] = handle; + MESSAGE("Library " << impl_name << " loaded"); + ret = true; + } + else + { + std::cerr << "Can't load shared library : " << impl_name << std::endl; + std::cerr << "error of dlopen: " << dlerror() << std::endl; + } } - else + + // --- try import Python component + if (!ret) { - cerr << "Can't load shared library : " << impl_name << endl; - cerr << "error dlopen: " << dlerror() << endl; - _numInstanceMutex.unlock(); - ret = false; + MESSAGE("Try to import Python component "<paco_barrier(); - + _numInstanceMutex.unlock(); return ret; } //============================================================================= +//! Create a new component instance /*! * CORBA method: Creates a new servant instance of a component. * The servant registers itself to naming service and Registry. * \param genericRegisterName Name of the component instance to register * in Registry & Name Service (without _inst_n suffix) - * \param studyId 0 for multiStudy instance, - * study Id (>0) otherwise * \return a loaded component */ //============================================================================= - -Engines::Component_ptr -Engines_Parallel_Container_i::create_component_instance(const char*genericRegisterName, - CORBA::Long studyId) +Engines::EngineComponent_ptr +Engines_Parallel_Container_i::create_component_instance(const char*genericRegisterName) { - cerr << "----------------- create_component_instance node : " << getMyRank() << endl; - - if (studyId < 0) - { - INFOS("studyId must be > 0 for mono study instance, =0 for multiStudy"); - return Engines::Component::_nil() ; - } + Engines::FieldsDict_var env = new Engines::FieldsDict; + char* reason; + Engines::EngineComponent_ptr compo = create_component_instance_env(genericRegisterName,env, reason); + CORBA::string_free(reason); + return compo; +} - Engines::Component_var iobject = Engines::Component::_nil() ; +//============================================================================= +//! Create a new component instance +/*! + * CORBA method: Creates a new servant instance of a component. + * The servant registers itself to naming service and Registry. + * \param genericRegisterName Name of the component instance to register + * in Registry & Name Service (without _inst_n suffix) + * \param env dict of environment variables + * \return a loaded component + */ +//============================================================================= - // is it a parallel component ? - bool parallel = false; - string aCompName = genericRegisterName; - int par = aCompName.find("@PARALLEL@"); - if (par>0) { - parallel = true; - aCompName = aCompName.substr(0,par); - } +Engines::EngineComponent_ptr +Engines_Parallel_Container_i::create_component_instance_env(const char*genericRegisterName, + const Engines::FieldsDict& env, + CORBA::String_out reason) +{ + MESSAGE("Begin of create_component_instance in node : " << getMyRank()); + reason=CORBA::string_dup(""); - //--- try C++ + std::string aCompName = genericRegisterName; #ifndef WIN32 - string impl_name = string ("lib") + aCompName +string("Engine.so"); +#ifdef __APPLE__ + std::string impl_name = string ("lib") + aCompName + string("Engine.dylib"); #else - string impl_name = aCompName +string("Engine.dll"); + std::string impl_name = string ("lib") + aCompName +string("Engine.so"); #endif - void* handle = _library_map[impl_name]; +#else + std::string impl_name = aCompName +string("Engine.dll"); +#endif + + _numInstanceMutex.lock(); + _numInstance++; - if ( !handle ) + // Test if the component lib is loaded + std::string type_of_lib("Not Loaded"); + void* handle = _library_map[impl_name]; + if (handle) + type_of_lib = "cpp"; + if (_library_map.count(aCompName) != 0 && !handle) + type_of_lib = "python"; + + if (type_of_lib == "Not Loaded") { - cerr << "shared library " << impl_name <<"must be loaded before instance" << endl;; - return Engines::Component::_nil() ; + std::cerr << "Component library is not loaded or imported ! lib was : " << aCompName << std::endl; + _numInstanceMutex.unlock(); + return Engines::EngineComponent::_nil(); } - else - { - if (parallel) { - // Sequential component case - // Component parallel proxy created on node 0 - iobject = createParallelInstance(aCompName, - handle, - studyId); - } - else { - // Sequential component case - iobject = createInstance(aCompName, - handle, - studyId); - } + Engines::EngineComponent_var iobject = Engines::EngineComponent::_nil(); + if (type_of_lib == "cpp") + iobject = createCPPInstance(aCompName, handle); + else + iobject = createPythonInstance(aCompName); - return iobject._retn(); - } + _numInstanceMutex.unlock(); + return iobject._retn(); } //============================================================================= +//! Find an existing (in the container) component instance /*! * CORBA method: Finds a servant instance of a component * \param registeredName Name of the component in Registry or Name Service, * without instance suffix number - * \param studyId 0 if instance is not associated to a study, - * >0 otherwise (== study id) - * \return the first instance found with same studyId + * \return the first found instance */ //============================================================================= -Engines::Component_ptr Engines_Parallel_Container_i::find_component_instance( const char* registeredName, - CORBA::Long studyId) +Engines::EngineComponent_ptr Engines_Parallel_Container_i::find_component_instance(const char* registeredName) { - Engines::Component_var anEngine = Engines::Component::_nil(); - map::iterator itm =_listInstances_map.begin(); + Engines::EngineComponent_var anEngine = Engines::EngineComponent::_nil(); + std::map::iterator itm =_listInstances_map.begin(); while (itm != _listInstances_map.end()) { - string instance = (*itm).first; + std::string instance = (*itm).first; SCRUTE(instance); if (instance.find(registeredName) == 0) { anEngine = (*itm).second; - if (studyId == anEngine->getStudyId()) - { - return anEngine._retn(); - } + return anEngine._retn(); } itm++; } return anEngine._retn(); } +char* Engines_Parallel_Container_i::create_python_service_instance(const char* CompName, + CORBA::String_out reason) +{ + // not implemented + reason=CORBA::string_dup(""); + return CORBA::string_dup(""); +} + //============================================================================= +//! Find or create a new component instance /*! * CORBA method: find or create an instance of the component (servant), * load a new component class (dynamic library) if required, @@ -385,35 +503,48 @@ Engines::Component_ptr Engines_Parallel_Container_i::find_component_instance( co */ //============================================================================= -Engines::Component_ptr Engines_Parallel_Container_i::load_impl( const char* genericRegisterName, - const char* componentName ) +Engines::EngineComponent_ptr Engines_Parallel_Container_i::load_impl( const char* genericRegisterName, + const char* componentName ) { - string impl_name = string ("lib") + genericRegisterName +string("Engine.so"); - Engines::Component_var iobject = Engines::Component::_nil() ; - if (load_component_Library(genericRegisterName)) - iobject = find_or_create_instance(genericRegisterName, impl_name); + Engines::EngineComponent_var iobject = Engines::EngineComponent::_nil(); + char* reason; + if (load_component_Library(genericRegisterName,reason)) + iobject = find_or_create_instance(genericRegisterName); + CORBA::string_free(reason); return iobject._retn(); } //============================================================================= +//! Remove the component instance from container /*! * CORBA method: Stops the component servant, and deletes all related objects * \param component_i Component to be removed */ //============================================================================= -void Engines_Parallel_Container_i::remove_impl(Engines::Component_ptr component_i) +void Engines_Parallel_Container_i::remove_impl(Engines::EngineComponent_ptr component_i) { - ASSERT(! CORBA::is_nil(component_i)); - string instanceName = component_i->instanceName() ; - MESSAGE("unload component " << instanceName); - _listInstances_map.erase(instanceName); - component_i->destroy() ; - _NS->Destroy_Name(instanceName.c_str()); + ASSERT(!CORBA::is_nil(component_i)); + std::string instanceName = component_i->instanceName(); + _numInstanceMutex.lock() ; // lock to be alone (stl container write) + // Test if the component is in this container + std::map::iterator itm; + itm = _listInstances_map.find(instanceName); + if (itm != _listInstances_map.end()) + { + MESSAGE("Unloading component " << instanceName); + _listInstances_map.erase(instanceName); + component_i->destroy() ; + _NS->Destroy_Name(instanceName.c_str()); + } + else + std::cerr << "WARNING !!!! component instance was not in this container !!!" << std::endl; + _numInstanceMutex.unlock() ; } //============================================================================= +//! Unload component libraries from the container /*! * CORBA method: Discharges unused libraries from the container. */ @@ -421,27 +552,31 @@ void Engines_Parallel_Container_i::remove_impl(Engines::Component_ptr component_ void Engines_Parallel_Container_i::finalize_removal() { - MESSAGE("finalize unload : dlclose"); - _numInstanceMutex.lock(); // lock to be alone + MESSAGE("Finalize removal : dlclose"); + MESSAGE("WARNING FINALIZE DOES CURRENTLY NOTHING !!!"); + // (see decInstanceCnt, load_component_Library) - map::iterator ith; - for (ith = _toRemove_map.begin(); ith != _toRemove_map.end(); ith++) - { - void *handle = (*ith).second; - string impl_name= (*ith).first; - if (handle) - { - SCRUTE(handle); - SCRUTE(impl_name); - // dlclose(handle); // SALOME unstable after ... - // _library_map.erase(impl_name); - } - } + //std::map::iterator ith; + //for (ith = _toRemove_map.begin(); ith != _toRemove_map.end(); ith++) + //{ + // void *handle = (*ith).second; + // std::string impl_name= (*ith).first; + // if (handle) + // { + // SCRUTE(handle); + // SCRUTE(impl_name); + // dlclose(handle); // SALOME unstable after ... + // _library_map.erase(impl_name); + // } + //} + + _numInstanceMutex.lock(); // lock to be alone _toRemove_map.clear(); _numInstanceMutex.unlock(); } //============================================================================= +//! Kill the container /*! * CORBA method: Kill the container process with exit(0). * To remove : never returns ! @@ -450,9 +585,9 @@ void Engines_Parallel_Container_i::finalize_removal() bool Engines_Parallel_Container_i::Kill_impl() { - MESSAGE("Engines_Parallel_Container_i::Kill() pid "<< getpid() << " containerName " - << _containerName.c_str() << " machineName " - << Kernel_Utils::GetHostname().c_str()); + MESSAGE("Engines_Parallel_Container_i::Kill() my pid is "<< _pid + << " my containerName is " << _containerName.c_str() + << " my machineName is " << _hostname.c_str()); INFOS("==============================================================="); INFOS("= REMOVE calls to Kill_impl in C++ container ="); INFOS("==============================================================="); @@ -461,7 +596,96 @@ bool Engines_Parallel_Container_i::Kill_impl() return false; } +//============================================================================= +//! Get or create a file reference object associated to a local file (to transfer it) +/*! + * CORBA method: get or create a fileRef object associated to a local file + * (a file on the computer on which runs the container server), which stores + * a list of (machine, localFileName) corresponding to copies already done. + * + * \param origFileName absolute path for a local file to copy on other + * computers + * \return a fileRef object associated to the file. + */ +//============================================================================= + +Engines::fileRef_ptr +Engines_Parallel_Container_i::createFileRef(const char* origFileName) +{ + std::string origName(origFileName); + Engines::fileRef_var theFileRef = Engines::fileRef::_nil(); + + if (origName[0] != '/') + { + INFOS("path of file to copy must be an absolute path beginning with '/'"); + return Engines::fileRef::_nil(); + } + + if (CORBA::is_nil(_fileRef_map[origName])) + { + CORBA::Object_var obj=_poa->id_to_reference(*_id); + Engines::Container_var pCont = Engines::Container::_narrow(obj); + fileRef_i* aFileRef = new fileRef_i(pCont, origFileName); + theFileRef = Engines::fileRef::_narrow(aFileRef->_this()); + _numInstanceMutex.lock() ; // lock to be alone (stl container write) + _fileRef_map[origName] = theFileRef; + _numInstanceMutex.unlock() ; + } + + theFileRef = Engines::fileRef::_duplicate(_fileRef_map[origName]); + ASSERT(! CORBA::is_nil(theFileRef)); + return theFileRef._retn(); +} + //============================================================================= +/*! + * CORBA method: + * \return a reference to the fileTransfer object + */ +//============================================================================= + +Engines::fileTransfer_ptr +Engines_Parallel_Container_i::getFileTransfer() +{ + Engines::fileTransfer_var aFileTransfer + = Engines::fileTransfer::_duplicate(_fileTransfer); + return aFileTransfer._retn(); +} + + +Engines::Salome_file_ptr +Engines_Parallel_Container_i::createSalome_file(const char* origFileName) +{ + string origName(origFileName); + if (CORBA::is_nil(_Salome_file_map[origName])) + { + Salome_file_i* aSalome_file = new Salome_file_i(); + try + { + aSalome_file->setLocalFile(origFileName); + aSalome_file->recvFiles(); + } + catch (const SALOME::SALOME_Exception& e) + { + return Engines::Salome_file::_nil(); + } + + Engines::Salome_file_var theSalome_file = Engines::Salome_file::_nil(); + theSalome_file = Engines::Salome_file::_narrow(aSalome_file->_this()); + _numInstanceMutex.lock() ; // lock to be alone (stl container write) + _Salome_file_map[origName] = theSalome_file; + _numInstanceMutex.unlock() ; + } + + Engines::Salome_file_ptr theSalome_file = + Engines::Salome_file::_duplicate(_Salome_file_map[origName]); + ASSERT(!CORBA::is_nil(theSalome_file)); + return theSalome_file; +} + + +//============================================================================= +//! Finds an already existing component instance or create a new instance /*! * C++ method: Finds an already existing servant instance of a component, or * create an instance. @@ -469,7 +693,6 @@ bool Engines_Parallel_Container_i::Kill_impl() * \param genericRegisterName Name of the component instance to register * in Registry & Name Service, * (without _inst_n suffix, like "COMPONENT") - * \param componentLibraryName like "libCOMPONENTEngine.so" * \return a loaded component * * example with names: @@ -484,74 +707,40 @@ bool Engines_Parallel_Container_i::Kill_impl() */ //============================================================================= -Engines::Component_ptr -Engines_Parallel_Container_i::find_or_create_instance(string genericRegisterName, - string componentLibraryName) +Engines::EngineComponent_ptr +Engines_Parallel_Container_i::find_or_create_instance(std::string genericRegisterName) { - string aGenRegisterName = genericRegisterName; - string impl_name = componentLibraryName; - void* handle = _library_map[impl_name]; - if ( !handle ) - { - INFOS("shared library " << impl_name <<"must be loaded before instance"); - return Engines::Component::_nil() ; - } - else + Engines::EngineComponent_var iobject = Engines::EngineComponent::_nil(); + try { + std::string aGenRegisterName = genericRegisterName; // --- find a registered instance in naming service, or create - - string component_registerBase = - _containerName + "/" + aGenRegisterName; - Engines::Component_var iobject = Engines::Component::_nil() ; - try + std::string component_registerBase = _containerName + "/" + aGenRegisterName; + CORBA::Object_var obj = _NS->ResolveFirst(component_registerBase.c_str()); + if (CORBA::is_nil( obj )) { - CORBA::Object_var obj = - _NS->ResolveFirst( component_registerBase.c_str()); - if ( CORBA::is_nil( obj ) ) - { - iobject = createInstance(genericRegisterName, - handle, - 0); // force multiStudy instance here ! - } - else - { - iobject = Engines::Component::_narrow( obj ) ; - Engines_Component_i *servant = - dynamic_cast - (_poa->reference_to_servant(iobject)); - ASSERT(servant) - int studyId = servant->getStudyId(); - ASSERT (studyId >= 0); - if (studyId == 0) // multiStudy instance, OK - { - // No ReBind ! - MESSAGE(component_registerBase.c_str()<<" already bound"); - } - else // monoStudy instance: NOK - { - iobject = Engines::Component::_nil(); - INFOS("load_impl & find_component_instance methods " - << "NOT SUITABLE for mono study components"); - } - } + iobject = create_component_instance(genericRegisterName.c_str()); } - catch (...) - { - INFOS( "Container_i::load_impl catched" ) ; + else + { + iobject = Engines::EngineComponent::_narrow(obj) ; } - return iobject._retn(); } + catch (...) + { + INFOS( "Container_i::load_impl caught" ) ; + } + return iobject._retn(); } //============================================================================= +//! Create a new Python component instance /*! * C++ method: create a servant instance of a component. * \param genericRegisterName Name of the component instance to register * in Registry & Name Service, * (without _inst_n suffix, like "COMPONENT") * \param handle loaded library handle - * \param studyId 0 for multiStudy instance, - * study Id (>0) otherwise * \return a loaded component * * example with names: @@ -563,270 +752,270 @@ Engines_Parallel_Container_i::find_or_create_instance(string genericRegisterName * component_registerName = /Containers/cli76ce/FactoryServer/COMPONENT_inst_1 */ //============================================================================= +Engines::EngineComponent_ptr +Engines_Parallel_Container_i::createPythonInstance(std::string genericRegisterName) +{ + + Engines::EngineComponent_var iobject = Engines::EngineComponent::_nil(); + + int numInstance = _numInstance; + char aNumI[12]; + sprintf( aNumI , "%d" , numInstance ) ; + std::string instanceName = genericRegisterName + "_inst_" + aNumI ; + std::string component_registerName = _containerName + "/" + instanceName; + + Py_ACQUIRE_NEW_THREAD; + PyObject *mainmod = PyImport_AddModule("__main__"); + PyObject *globals = PyModule_GetDict(mainmod); + PyObject *pyCont = PyDict_GetItemString(globals, "pyCont"); + PyObject *result = PyObject_CallMethod(pyCont, + (char*)"create_component_instance", + (char*)"ss", + genericRegisterName.c_str(), + instanceName.c_str()); + const char *ior; + const char *error; + PyArg_ParseTuple(result,"ss", &ior, &error); + string iors = ior; + Py_DECREF(result); + Py_RELEASE_NEW_THREAD; + + if( iors!="" ) + { + CORBA::Object_var obj = _orb->string_to_object(iors.c_str()); + iobject = Engines::EngineComponent::_narrow(obj); + _listInstances_map[instanceName] = iobject; + } + else + std::cerr << "createPythonInstance ior is empty ! Error in creation" << std::endl; -Engines::Component_ptr -Engines_Parallel_Container_i::createInstance(string genericRegisterName, - void *handle, - int studyId) + return iobject._retn(); +} + +//============================================================================= +//! Create a new CPP component instance +/*! + * C++ method: create a servant instance of a component. + * \param genericRegisterName Name of the component instance to register + * in Registry & Name Service, + * (without _inst_n suffix, like "COMPONENT") + * \param handle loaded library handle + * \return a loaded component + * + * example with names: + * aGenRegisterName = COMPONENT (= first argument) + * _containerName = /Containers/cli76ce/FactoryServer + * factoryName = COMPONENTEngine_factory + * component_registerBase = /Containers/cli76ce/FactoryServer/COMPONENT + * instanceName = COMPONENT_inst_1 + * component_registerName = /Containers/cli76ce/FactoryServer/COMPONENT_inst_1 + */ +//============================================================================= +Engines::EngineComponent_ptr +Engines_Parallel_Container_i::createCPPInstance(std::string genericRegisterName, + void *handle) { - // --- find the factory + MESSAGE("Entering Engines_Parallel_Container_i::createCPPInstance"); - string aGenRegisterName = genericRegisterName; - string factory_name = aGenRegisterName + string("Engine_factory"); + // --- find the factory - SCRUTE(factory_name) ; + std::string aGenRegisterName = genericRegisterName; + std::string factory_name = aGenRegisterName + string("Engine_factory"); - typedef PortableServer::ObjectId * (*FACTORY_FUNCTION) + typedef PortableServer::ObjectId * (*FACTORY_FUNCTION_2) (CORBA::ORB_ptr, PortableServer::POA_ptr, PortableServer::ObjectId *, const char *, const char *) ; - FACTORY_FUNCTION Component_factory - = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str()); + FACTORY_FUNCTION_2 Component_factory = NULL; +#ifndef WIN32 + Component_factory = (FACTORY_FUNCTION_2)dlsym( handle, factory_name.c_str() ); +#else + Component_factory = (FACTORY_FUNCTION_2)GetProcAddress( (HINSTANCE)handle, factory_name.c_str() ); +#endif - char *error ; - if ( (error = dlerror() ) != NULL) + if (!Component_factory) { INFOS("Can't resolve symbol: " + factory_name); - SCRUTE(error); - return Engines::Component::_nil() ; +#ifndef WIN32 + INFOS("dlerror() result is : " << dlerror()); +#endif + return Engines::EngineComponent::_nil() ; } // --- create instance - Engines::Component_var iobject = Engines::Component::_nil() ; + Engines::EngineComponent_var iobject = Engines::EngineComponent::_nil() ; try { - _numInstanceMutex.lock() ; // lock on the instance number - _numInstance++ ; - int numInstance = _numInstance ; - _numInstanceMutex.unlock() ; - + int numInstance = _numInstance; char aNumI[12]; - sprintf( aNumI , "%d" , numInstance ) ; - string instanceName = aGenRegisterName + "_inst_" + aNumI ; - string component_registerName = + sprintf( aNumI , "%d" , numInstance ); + std::string instanceName = aGenRegisterName + "_inst_" + aNumI; + std::string component_registerName = _containerName + "/" + instanceName; - // --- Instanciate required CORBA object + // --- Instantiate required CORBA object - PortableServer::ObjectId *id ; //not owner, do not delete (nore use var) + PortableServer::ObjectId *id; //not owner, do not delete (nore use var) id = (Component_factory) ( _orb, _poa, _id, instanceName.c_str(), - aGenRegisterName.c_str() ) ; + aGenRegisterName.c_str() ); + if (id == NULL) + { + INFOS("Factory function returns NULL !"); + return iobject._retn(); + } - // --- get reference & servant from id + // --- get reference from id CORBA::Object_var obj = _poa->id_to_reference(*id); - iobject = Engines::Component::_narrow(obj) ; + iobject = Engines::EngineComponent::_narrow(obj); - Engines_Component_i *servant = - dynamic_cast(_poa->reference_to_servant(iobject)); - ASSERT(servant); - servant->_remove_ref(); // compensate previous id_to_reference _listInstances_map[instanceName] = iobject; _cntInstances_map[aGenRegisterName] += 1; - bool ret_studyId = servant->setStudyId(studyId); - ASSERT(ret_studyId); // --- register the engine under the name // containerName(.dir)/instanceName(.object) - _NS->Register(iobject , component_registerName.c_str()) ; - MESSAGE( component_registerName.c_str() << " bound" ) ; + _NS->Register(iobject , component_registerName.c_str()); + MESSAGE( component_registerName.c_str() << " bound" ); } catch (...) { - INFOS( "Container_i::createInstance exception catched" ) ; + INFOS( "Container_i::createInstance exception caught" ); } return iobject._retn(); } -Engines::Component_ptr -Engines_Parallel_Container_i::createParallelInstance(string genericRegisterName, - void *handle, - int studyId) +void +Engines_Parallel_Container_i::create_paco_component_node_instance(const char* componentName, + const char* proxy_containerName) { - cerr << "----------------- createParallelInstance node : " << getMyRank() << endl; - // --- create instance - Engines::Component_var iobject = Engines::Component::_nil(); - string aGenRegisterName = genericRegisterName; - - ////////////////////////////////////////////////////////////////////////// - // 1: Proxy Step - // Node 0 create the proxy - if (getMyRank() == 0) { - // --- find the factory - string factory_name = aGenRegisterName + string("EngineProxy_factory"); - - typedef PortableServer::ObjectId * (*FACTORY_FUNCTION) - (CORBA::ORB_ptr, - paco_fabrique_thread *, - PortableServer::POA_ptr, - PortableServer::ObjectId *, - const char *, - int) ; - - FACTORY_FUNCTION Component_factory - = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str()); - - char *error ; - if ( (error = dlerror() ) != NULL) { - INFOS("Can't resolve symbol: " + factory_name); - SCRUTE(error); - return Engines::Component::_nil(); - } - try { - _numInstanceMutex.lock() ; // lock on the instance number - _numInstance++ ; - int numInstance = _numInstance ; - _numInstanceMutex.unlock() ; - - char aNumI[12]; - sprintf( aNumI , "%d" , numInstance ) ; - string instanceName = aGenRegisterName + "_inst_" + aNumI ; - string component_registerName = - _containerName + "/" + instanceName; - - // --- Instanciate required CORBA object - PortableServer::ObjectId *id ; //not owner, do not delete (nore use var) - id = (Component_factory) ( _orb, new paco_omni_fabrique(), _poa, _id, instanceName.c_str(), getTotalNode()) ; - - // --- get reference & servant from id - CORBA::Object_var obj = _poa->id_to_reference(*id); - iobject = Engines::Component::_narrow(obj) ; - - _listInstances_map[instanceName] = iobject; - _cntInstances_map[aGenRegisterName] += 1; - - // --- register the engine under the name - // containerName(.dir)/instanceName(.object) - _NS->Register(iobject , component_registerName.c_str()) ; - MESSAGE( component_registerName.c_str() << " bound" ) ; - } - catch (...) - { - INFOS( "Container_i::createParallelInstance exception catched in Proxy creation" ) ; - } - } - else { - // We have to have the same numIntance to be able to get the proxy reference - // in the nameing service. - _numInstanceMutex.lock() ; // lock on the instance number - _numInstance++ ; - // int numInstance = _numInstance ; - _numInstanceMutex.unlock() ; - } - cerr << "Node " << getMyRank() << " entering in paco_barrier()" << endl; - _my_com->paco_barrier(); - cerr << "Node " << getMyRank() << " quitting paco_barrier()" << endl; - - ////////////////////////////////////////////////////////////////////////// - // 2: Nodes Step - + // Init de la méthode char * proxy_ior; - Engines::Component_PaCO_var iobject2; + Engines::EngineComponent_PaCO_var work_node; + std::string aCompName = componentName; + std::string _proxy_containerName = proxy_containerName; +#ifndef WIN32 +#ifdef __APPLE__ + string impl_name = string ("lib") + aCompName + string("Engine.dylib"); +#else + string impl_name = string ("lib") + aCompName +string("Engine.so"); +#endif +#else + string impl_name = aCompName +string("Engine.dll"); +#endif + void* handle = _library_map[impl_name]; + _numInstanceMutex.lock() ; // lock on the instance number + _numInstance++ ; + int numInstance = _numInstance ; + _numInstanceMutex.unlock() ; char aNumI[12]; - sprintf( aNumI , "%d" , _numInstance ) ; - string instanceName = aGenRegisterName + "_inst_" + aNumI ; - - string component_registerName = _containerName + "/" + instanceName; - string hostname = Kernel_Utils::GetHostname(); + sprintf( aNumI , "%d" , numInstance ) ; + string instanceName = aCompName + "_inst_" + aNumI ; + // Step 1 : Get proxy ! + string component_registerName = _proxy_containerName + "/" + instanceName; CORBA::Object_var temp = _NS->Resolve(component_registerName.c_str()); - Engines::Component_var obj_proxy = Engines::Component::_narrow(temp); + Engines::EngineComponent_var obj_proxy = Engines::EngineComponent::_narrow(temp); + if (CORBA::is_nil(obj_proxy)) + { + INFOS("Proxy reference from NamingService is nil !"); + INFOS("Proxy name was : " << component_registerName); + SALOME::ExceptionStruct es; + es.type = SALOME::INTERNAL_ERROR; + es.text = "Proxy reference from NamingService is nil !"; + throw SALOME::SALOME_Exception(es); + } proxy_ior = _orb->object_to_string(obj_proxy); - // --- find the factory - string factory_name = aGenRegisterName + string("Engine_factory"); - - typedef PortableServer::ObjectId * (*FACTORY_FUNCTION) - (CORBA::ORB_ptr, char *, int, - PortableServer::POA_ptr, - PortableServer::ObjectId *, - const char *, - const char *) ; - - FACTORY_FUNCTION Component_factory - = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str()); - - char *error ; - if ( (error = dlerror() ) != NULL) + // Get factory + string factory_name = aCompName + string("Engine_factory"); + FACTORY_FUNCTION Component_factory = (FACTORY_FUNCTION) dlsym(handle, factory_name.c_str()); + if (!Component_factory) { - INFOS("Can't resolve symbol: " + factory_name); - SCRUTE(error); - return Engines::Component::_nil() ; + INFOS("Can't resolve symbol : " + factory_name); +#ifndef WIN32 + INFOS("dlerror() result is : " << dlerror()); +#endif + std::string ex_text = "Can't resolve symbol : " + factory_name; + SALOME::ExceptionStruct es; + es.type = SALOME::INTERNAL_ERROR; + es.text = CORBA::string_dup(ex_text.c_str()); + throw SALOME::SALOME_Exception(es); } + try { char aNumI2[12]; sprintf(aNumI2 , "%d" , getMyRank()) ; - string instanceName = aGenRegisterName + "_inst_node_" + aNumI2; - string component_registerName = _containerName + aNumI2 + "/" + instanceName; - - // --- Instanciate required CORBA object + std::string instanceName = aCompName + "_inst_" + aNumI + "_work_node_" + aNumI2; + std::string component_registerName = _containerName + "/" + instanceName; + // --- Instantiate work node PortableServer::ObjectId *id ; //not owner, do not delete (nore use var) - id = (Component_factory) ( _orb, proxy_ior, getMyRank(), _poa, _id, instanceName.c_str(), - aGenRegisterName.c_str() ) ; + id = (Component_factory) (_orb, proxy_ior, getMyRank(), _poa, _id, instanceName.c_str(), componentName); + CORBA::string_free(proxy_ior); - // --- get reference & servant from id + // --- get reference from id CORBA::Object_var obj = _poa->id_to_reference(*id); - iobject2 = Engines::Component_PaCO::_narrow(obj) ; - - // --- register the engine under the name - _NS->Register(iobject2 , component_registerName.c_str()) ; - MESSAGE( component_registerName.c_str() << " bound" ) ; + work_node = Engines::EngineComponent_PaCO::_narrow(obj) ; + if (CORBA::is_nil(work_node)) + { + INFOS("work_node reference from factory is nil !"); + SALOME::ExceptionStruct es; + es.type = SALOME::INTERNAL_ERROR; + es.text = "work_node reference from factory is nil !"; + throw SALOME::SALOME_Exception(es); + } + work_node->deploy(); + _NS->Register(work_node, component_registerName.c_str()); + _par_obj_inst_map[instanceName] = id; + MESSAGE(component_registerName.c_str() << " bound" ); } catch (...) { - INFOS( "Container_i::createParallelInstance exception catched" ) ; - } - - ////////////////////////////////////////////////////////////////////////// - // 3: Deployment Step - - iobject2->deploy(); - _my_com->paco_barrier(); - cerr << "--------- createParallelInstance : End Deploy step ----------" << endl; - if (getMyRank() == 0) { - PaCO::InterfaceManager_var proxy = PaCO::InterfaceManager::_narrow(iobject); - proxy->start(); - _my_com->paco_barrier(); + INFOS("Container_i::create_paco_component_node_instance exception caught"); + SALOME::ExceptionStruct es; + es.type = SALOME::INTERNAL_ERROR; + es.text = "Container_i::create_paco_component_node_instance exception caught"; + throw SALOME::SALOME_Exception(es); } - else - _my_com->paco_barrier(); - - return iobject._retn(); } //============================================================================= +//! Decrement component instance reference count /*! * */ //============================================================================= -void Engines_Parallel_Container_i::decInstanceCnt(string genericRegisterName) +void Engines_Parallel_Container_i::decInstanceCnt(std::string genericRegisterName) { - string aGenRegisterName =genericRegisterName; - MESSAGE("Engines_Parallel_Container_i::decInstanceCnt " << aGenRegisterName); - ASSERT(_cntInstances_map[aGenRegisterName] > 0); - _numInstanceMutex.lock(); // lock to be alone - // (see finalize_removal, load_component_Library) - _cntInstances_map[aGenRegisterName] -= 1; - SCRUTE(_cntInstances_map[aGenRegisterName]); - if (_cntInstances_map[aGenRegisterName] == 0) + if(_cntInstances_map.count(genericRegisterName) !=0 ) { - string impl_name = - Engines_Component_i::GetDynLibraryName(aGenRegisterName.c_str()); - SCRUTE(impl_name); - void* handle = _library_map[impl_name]; - ASSERT(handle); - _toRemove_map[impl_name] = handle; + std::string aGenRegisterName =genericRegisterName; + MESSAGE("Engines_Parallel_Container_i::decInstanceCnt " << aGenRegisterName); + ASSERT(_cntInstances_map[aGenRegisterName] > 0); + _numInstanceMutex.lock(); // lock to be alone + // (see finalize_removal, load_component_Library) + _cntInstances_map[aGenRegisterName] -= 1; + SCRUTE(_cntInstances_map[aGenRegisterName]); + if (_cntInstances_map[aGenRegisterName] == 0) + { + std::string impl_name = + Engines_Component_i::GetDynLibraryName(aGenRegisterName.c_str()); + SCRUTE(impl_name); + void* handle = _library_map[impl_name]; + ASSERT(handle); + _toRemove_map[impl_name] = handle; + } + _numInstanceMutex.unlock(); } - _numInstanceMutex.unlock(); } //============================================================================= +//! Indicate if container is a python one /*! * Retrieves only with container naming convention if it is a python container */ @@ -835,13 +1024,103 @@ void Engines_Parallel_Container_i::decInstanceCnt(string genericRegisterName) bool Engines_Parallel_Container_i::isPythonContainer(const char* ContainerName) { bool ret=false; - int len=strlen(ContainerName); - if(len>=2) - if(strcmp(ContainerName+len-2,"Py")==0) - ret=true; return ret; } + +// Cette méthode permet de tenir à jour le compteur des +// instances pour le container parallèle. +// En effet losrque l'on charge un composant séquentielle seul +// le compteur du noeud 0 est augmenté, il faut donc tenir les autres +// noeuds à jour. +void +Engines_Parallel_Container_i::updateInstanceNumber() +{ + if (getMyRank() != 0) + { + _numInstanceMutex.lock(); + _numInstance++; + _numInstanceMutex.unlock(); + } +} + +/*! \brief copy a file from a remote host (container) to the local host + * \param container the remote container + * \param remoteFile the file to copy locally from the remote host into localFile + * \param localFile the local file + */ +void +Engines_Parallel_Container_i::copyFile(Engines::Container_ptr container, const char* remoteFile, const char* localFile) +{ + Engines::fileTransfer_var fileTransfer = container->getFileTransfer(); + + FILE* fp; + if ((fp = fopen(localFile,"wb")) == NULL) + { + INFOS("file " << localFile << " cannot be open for writing"); + return; + } + + CORBA::Long fileId = fileTransfer->open(remoteFile); + if (fileId > 0) + { + Engines::fileBlock* aBlock; + int toFollow = 1; + int ctr=0; + while (toFollow) + { + ctr++; + SCRUTE(ctr); + aBlock = fileTransfer->getBlock(fileId); + toFollow = aBlock->length(); + SCRUTE(toFollow); + CORBA::Octet *buf = aBlock->get_buffer(); + fwrite(buf, sizeof(CORBA::Octet), toFollow, fp); + delete aBlock; + } + fclose(fp); + MESSAGE("end of transfer"); + fileTransfer->close(fileId); + } + else + { + INFOS("open reference file for copy impossible"); + } +} + +/*! \brief create a PyNode object to execute remote python code + * \param nodeName the name of the node + * \param code the python code to load + * \return the PyNode + */ +Engines::PyNode_ptr +Engines_Parallel_Container_i::createPyNode(const char* nodeName, const char* code) +{ + INFOS("Python component not yet implemented"); + Engines::PyNode_var node= Engines::PyNode::_nil(); + return node._retn(); +} + +Engines::PyNode_ptr Engines_Parallel_Container_i::getDefaultPyNode(const char *nodeName) +{ + INFOS("Python component not yet implemented"); + return Engines::PyNode::_nil(); +} + +Engines::PyScriptNode_ptr +Engines_Parallel_Container_i::createPyScriptNode(const char* nodeName, const char* cod) +{ + INFOS("Python script node not yet implemented"); + Engines::PyScriptNode_var node= Engines::PyScriptNode::_nil(); + return node._retn(); +} + +Engines::PyScriptNode_ptr Engines_Parallel_Container_i::getDefaultPyScriptNode(const char *nodeName) +{ + INFOS("Python script node not yet implemented"); + return Engines::PyScriptNode::_nil(); +} + //============================================================================= /*! * @@ -860,6 +1139,7 @@ void ActSigIntHandler() // (SIGINT | SIGUSR1) : // it must be only one signal ===> one call for SIGINT // and an other one for SIGUSR1 + #ifndef WIN32 if ( sigaction( SIGINT , &SigIntAct, NULL ) ) { perror("SALOME_Container main ") ; @@ -869,6 +1149,12 @@ void ActSigIntHandler() perror("SALOME_Container main ") ; exit(0) ; } + if ( sigaction( SIGUSR2 , &SigIntAct, NULL ) ) + { + perror("SALOME_Container main ") ; + exit(0) ; + } + //PAL9042 JR : during the execution of a Signal Handler (and of methods called through Signal Handlers) // use of streams (and so on) should never be used because : // streams of C++ are naturally thread-safe and use pthread_mutex_lock ===> @@ -883,11 +1169,12 @@ void ActSigIntHandler() } -void SetCpuUsed() ; +void SetCpuUsed(); +void CallCancelThread(); #ifndef WIN32 void SigIntHandler(int what , siginfo_t * siginfo , - void * toto ) { + void * toto ) { //PAL9042 JR : during the execution of a Signal Handler (and of methods called through Signal Handlers) // use of streams (and so on) should never be used because : // streams of C++ are naturally thread-safe and use pthread_mutex_lock ===> @@ -908,13 +1195,17 @@ void SigIntHandler(int what , siginfo_t * siginfo , if ( siginfo->si_signo == SIGUSR1 ) { SetCpuUsed() ; } + else if ( siginfo->si_signo == SIGUSR2 ) + { + CallCancelThread() ; + } else { _Sleeping = true ; // MESSAGE("SigIntHandler BEGIN sleeping.") ; int count = 0 ; while( _Sleeping ) { - sleep( 1 ) ; - count += 1 ; + sleep( 1 ) ; + count += 1 ; } // MESSAGE("SigIntHandler LEAVE sleeping after " << count << " s.") ; } @@ -939,8 +1230,8 @@ void SigIntHandler( int what ) { MESSAGE("SigIntHandler BEGIN sleeping.") ; int count = 0 ; while( _Sleeping ) { - Sleep( 1000 ) ; - count += 1 ; + Sleep( 1000 ) ; + count += 1 ; } MESSAGE("SigIntHandler LEAVE sleeping after " << count << " s.") ; } @@ -948,121 +1239,3 @@ void SigIntHandler( int what ) { } } #endif - -//============================================================================= -/*! - * CORBA method: get or create a fileRef object associated to a local file - * (a file on the computer on which runs the container server), which stores - * a list of (machine, localFileName) corresponding to copies already done. - * - * \param origFileName absolute path for a local file to copy on other - * computers - * \return a fileRef object associated to the file. - */ -//============================================================================= - -Engines::fileRef_ptr -Engines_Parallel_Container_i::createFileRef(const char* origFileName) -{ - string origName(origFileName); - Engines::fileRef_var theFileRef = Engines::fileRef::_nil(); - - if (origName[0] != '/') - { - INFOS("path of file to copy must be an absolute path begining with '/'"); - return Engines::fileRef::_nil(); - } - - if (CORBA::is_nil(_fileRef_map[origName])) - { - CORBA::Object_var obj=_poa->id_to_reference(*_id); - Engines::Container_var pCont = Engines::Container::_narrow(obj); - fileRef_i* aFileRef = new fileRef_i(pCont, origFileName); - theFileRef = Engines::fileRef::_narrow(aFileRef->_this()); - _numInstanceMutex.lock() ; // lock to be alone (stl container write) - _fileRef_map[origName] = theFileRef; - _numInstanceMutex.unlock() ; - } - - theFileRef = Engines::fileRef::_duplicate(_fileRef_map[origName]); - ASSERT(! CORBA::is_nil(theFileRef)); - return theFileRef._retn(); -} - -//============================================================================= -/*! - * CORBA method: - * \return a reference to the fileTransfer object - */ -//============================================================================= - -Engines::fileTransfer_ptr -Engines_Parallel_Container_i::getFileTransfer() -{ - Engines::fileTransfer_var aFileTransfer - = Engines::fileTransfer::_duplicate(_fileTransfer); - return aFileTransfer._retn(); -} - - -Engines::Salome_file_ptr -Engines_Parallel_Container_i::createSalome_file(const char* origFileName) -{ - string origName(origFileName); - if (CORBA::is_nil(_Salome_file_map[origName])) - { - Salome_file_i* aSalome_file = new Salome_file_i(); - try - { - aSalome_file->setLocalFile(origFileName); - aSalome_file->recvFiles(); - } - catch (const SALOME::SALOME_Exception& e) - { - return Engines::Salome_file::_nil(); - } - - Engines::Salome_file_var theSalome_file = Engines::Salome_file::_nil(); - theSalome_file = Engines::Salome_file::_narrow(aSalome_file->_this()); - _numInstanceMutex.lock() ; // lock to be alone (stl container write) - _Salome_file_map[origName] = theSalome_file; - _numInstanceMutex.unlock() ; - } - - Engines::Salome_file_ptr theSalome_file = - Engines::Salome_file::_duplicate(_Salome_file_map[origName]); - ASSERT(!CORBA::is_nil(theSalome_file)); - return theSalome_file; -} - -//============================================================================= -/*! - * CORBA attribute: Container working directory - */ -//============================================================================= - -char* -Engines_Parallel_Container_i::workingdir() -{ - char wd[256]; - getcwd (wd,256); - return CORBA::string_dup(wd) ; -} - -//============================================================================= -/*! - * CORBA attribute: Container log file name - */ -//============================================================================= - -char* -Engines_Parallel_Container_i::logfilename() -{ - return CORBA::string_dup(_logfilename.c_str()) ; -} - -void -Engines_Parallel_Container_i::logfilename(const char* name) -{ - _logfilename=name; -}