Salome HOME
updated copyright message
[modules/kernel.git] / src / MPIContainer / MPIContainer_i.cxx
index dfeb178e13579d792ccfb0b10b30e9d79103abae..b2f30116dce03f2283fcca8dfa1e378c35e7256a 100644 (file)
@@ -1,97 +1,69 @@
-//  SALOME MPIContainer : implemenation of container based on MPI libraries
+// Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
 //
-//  Copyright (C) 2003  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 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 
-// 
-//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+// 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, 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.
+//
+// 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
 //
-//  File   : MPIContainer_i.cxx
-//  Module : SALOME
 
-#include <iostream.h>
+#include <iostream>
 #include <dlfcn.h>
 #include <stdio.h>
+#include "Basics_Utils.hxx"
 #include "SALOME_Component_i.hxx"
 #include "MPIContainer_i.hxx"
 #include "SALOME_NamingService.hxx"
 #include "Utils_SINGLETON.hxx"
 #include "OpUtil.hxx"
 #include "utilities.h"
+#include <time.h>
+#include <sys/time.h>
 #include <pthread.h>  // must be before Python.h !
+
+#ifdef _XOPEN_SOURCE
+#undef _XOPEN_SOURCE
+#endif
+
 #include <Python.h>
 #include "Container_init_python.hxx"
-using namespace std;
 
 // L'appel au registry SALOME ne se fait que pour le process 0
-Engines_MPIContainer_i::Engines_MPIContainer_i(int nbproc, int numproc,
-                                              CORBA::ORB_ptr orb, 
-                                              PortableServer::POA_ptr poa,
-                                              char * containerName,
-                                              int argc, char *argv[]) 
-  : Engines_Container_i(orb,poa,containerName,argc,argv,false), MPIObject_i(nbproc,numproc)
+Engines_MPIContainer_i::Engines_MPIContainer_i(CORBA::ORB_ptr orb, 
+                                               PortableServer::POA_ptr poa,
+                                               char * containerName,
+                                               int argc, char *argv[]) 
+  : Engines_Container_i(orb,poa,containerName,argc,argv,nullptr,false)
 {
-  long id=0;
-  string IdContainerinNS;
-  char idc[3*sizeof(long)];
 
-  MESSAGE("[" << numproc << "] activate object");
   _id = _poa->activate_object(this);
+  CORBA::Object_var obj=_poa->id_to_reference(*_id);
+  Engines::Container_var pCont = Engines::Container::_narrow(obj);
+  _remove_ref();
 
-  if(argc>1)
-    {
-      for(int i=0;i<argc;i++)
-       {
-         if(strcmp(argv[i],"-id")==NULL)
-           {
-             id = atoi(argv[i+1]);
-             continue;
-           }
-       }
-    }
-  SCRUTE(id);
-
-  if(numproc==0){
+  if(_numproc==0){
 
     _NS = new SALOME_NamingService();
     _NS->init_orb( CORBA::ORB::_duplicate(_orb) ) ;
 
-    CORBA::Object_var obj=_poa->id_to_reference(*_id);
-    Engines::Container_var pCont = Engines::Container::_narrow(obj);
-
-    string hostname = GetHostname();
-    _containerName = _NS->BuildContainerNameForNS(containerName,hostname.c_str());
+    std::string hostname = Kernel_Utils::GetHostname();
+    _containerName = SALOME_NamingService_Abstract::BuildContainerNameForNS(containerName,hostname.c_str());
     SCRUTE(_containerName);
     _NS->Register(pCont, _containerName.c_str());
 
-    // A parallel container registers in Naming Service
-    // on the machine where is process 0. ContainerManager does'nt know the name
-    // of this machine before the launch of the parallel container. So to get
-    // the IOR of the parallel container in Naming Service, ContainerManager
-    // gives a unique Id. The parallel container registers his name under
-    // /ContainerManager/Id directory in NamingService
-
-    IdContainerinNS = "/ContainerManager/id";
-    sprintf(idc,"%ld",id);
-    IdContainerinNS += idc;
-    SCRUTE(IdContainerinNS);
-    _NS->Register(pCont, IdContainerinNS.c_str());
-
   }
 
   // Root recupere les ior des container des autre process
@@ -99,8 +71,8 @@ Engines_MPIContainer_i::Engines_MPIContainer_i(int nbproc, int numproc,
   BCastIOR(_orb,pobj,true);
 }
 
-Engines_MPIContainer_i::Engines_MPIContainer_i(int nbproc, int numproc
-  : Engines_Container_i(), MPIObject_i(nbproc,numproc)
+Engines_MPIContainer_i::Engines_MPIContainer_i() 
+  : Engines_Container_i()
 {
 }
 
@@ -116,38 +88,70 @@ void Engines_MPIContainer_i::Shutdown()
   MESSAGE("[" << _numproc << "] shutdown of MPI Corba Server");
   if( _numproc == 0 ){
     _NS->Destroy_FullDirectory(_containerName.c_str());
+    _NS->Destroy_Name(_containerName.c_str());
     for(ip= 1;ip<_nbproc;ip++)
       (Engines::MPIContainer::_narrow((*_tior)[ip]))->Shutdown();
   }
+
+  std::map<std::string, Engines::EngineComponent_var>::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
+        }
+    }
+
   _orb->shutdown(0);
 
 }
 
 // Load a component library
-bool Engines_MPIContainer_i::load_component_Library(const char* componentName)
+bool Engines_MPIContainer_i::load_component_Library(const char* componentName, CORBA::String_out reason)
 {
-  if( _numproc == 0 ){
-    // Invocation du chargement du composant dans les autres process
-    for(int ip= 1;ip<_nbproc;ip++)
-      (Engines::MPIContainer::_narrow((*_tior)[ip]))->Asload_component_Library(componentName);
+  reason=CORBA::string_dup("");
+
+  pthread_t *th = 0;
+  if(_numproc == 0){
+    th = new pthread_t[_nbproc];
+    for(int ip=1;ip<_nbproc;ip++){
+      thread_st *st = new thread_st;
+      st->ip = ip;
+      st->tior = _tior;
+      st->compoName = componentName;
+      pthread_create(&(th[ip]),NULL,th_loadcomponentlibrary,(void*)st);
+    }
   }
 
-  return Lload_component_Library(componentName);
-}
+  bool ret = Lload_component_Library(componentName);
 
-void Engines_MPIContainer_i::Asload_component_Library(const char* componentName)
-{
-  Lload_component_Library(componentName);
+  if(_numproc == 0){
+    for(int ip=1;ip<_nbproc;ip++)
+      pthread_join(th[ip],NULL);
+    delete th;
+  }
+  return ret;
 }
 
 bool Engines_MPIContainer_i::Lload_component_Library(const char* componentName)
 {
-  string aCompName = componentName;
+  std::string aCompName = componentName;
 
   // --- try dlopen C++ component
 
-  string impl_name = string ("lib") + aCompName + string("Engine.so");
-  SCRUTE(impl_name);
+#ifdef __APPLE__
+  std::string impl_name = std::string ("lib") + aCompName + std::string("Engine.dylib");
+#else
+  std::string impl_name = std::string ("lib") + aCompName + std::string("Engine.so");
+#endif
   
   _numInstanceMutex.lock(); // lock to be alone 
   // (see decInstanceCnt, finalize_removal))
@@ -160,17 +164,18 @@ bool Engines_MPIContainer_i::Lload_component_Library(const char* componentName)
     }
   
   void* handle;
-  handle = dlopen( impl_name.c_str() , RTLD_LAZY ) ;
+  handle = dlopen( impl_name.c_str() , RTLD_LAZY | RTLD_GLOBAL ) ;
   if ( handle )
     {
       _library_map[impl_name] = handle;
       _numInstanceMutex.unlock();
+      MESSAGE("[" << _numproc << "] Library " << impl_name << " loaded");
       return true;
     }
   else
     {
-      INFOS("[" << _numproc << "] Can't load shared library : " << impl_name);
-      INFOS("[" << _numproc << "] error dlopen: " << dlerror());
+      MESSAGE("[" << _numproc << "] Can't load shared library : " << impl_name);
+      MESSAGE("[" << _numproc << "] error dlopen: " << dlerror());
     }
   _numInstanceMutex.unlock();
 
@@ -189,62 +194,68 @@ bool Engines_MPIContainer_i::Lload_component_Library(const char* componentName)
   else
     {
       Py_ACQUIRE_NEW_THREAD;
-      PyObject *mainmod = PyImport_AddModule("__main__");
+      PyObject *mainmod = PyImport_AddModule((char *)"__main__");
       PyObject *globals = PyModule_GetDict(mainmod);
       PyObject *pyCont = PyDict_GetItemString(globals, "pyCont");
       PyObject *result = PyObject_CallMethod(pyCont,
-                                            "import_component",
-                                            "s",componentName);
-      int ret= PyInt_AsLong(result);
+                                             (char*)"import_component",
+                                             (char*)"s",componentName);
+      std::string ret= PyUnicode_AsUTF8(result);
       SCRUTE(ret);
       Py_RELEASE_NEW_THREAD;
   
-      if (ret) // import possible: Python component
-       {
-         _library_map[aCompName] = (void *)pyCont; // any non O value OK
-         MESSAGE("[" << _numproc << "] import Python: "<<aCompName<<" OK");
-         return true;
-       }
+      if (ret=="") // import possible: Python component
+        {
+          _library_map[aCompName] = (void *)pyCont; // any non O value OK
+          MESSAGE("[" << _numproc << "] import Python: "<<aCompName<<" OK");
+          return true;
+        }
     }
   return false;
 }
 
 // Create an instance of component
-Engines::Component_ptr
-Engines_MPIContainer_i::create_component_instance( const char* componentName,
-                                                  CORBA::Long studyId)
+Engines::EngineComponent_ptr
+Engines_MPIContainer_i::create_component_instance_env( const char* componentName,
+                                                       const Engines::FieldsDict& /*env*/,
+                                                       CORBA::String_out reason)
 {
-  if( _numproc == 0 ){
-    // Invocation du chargement du composant dans les autres process
-    for(int ip= 1;ip<_nbproc;ip++)
-      (Engines::MPIContainer::_narrow((*_tior)[ip]))->Ascreate_component_instance(componentName,studyId);
+  reason=CORBA::string_dup("");
+
+  pthread_t *th = 0;
+  if(_numproc == 0){
+    th = new pthread_t[_nbproc];
+    for(int ip=1;ip<_nbproc;ip++){
+      thread_st *st = new thread_st;
+      st->ip = ip;
+      st->tior = _tior;
+      st->compoName = componentName;
+      pthread_create(&(th[ip]),NULL,th_createcomponentinstance,(void*)st);
+    }
   }
 
-  return Lcreate_component_instance(componentName,studyId);
-}
+  Engines::EngineComponent_ptr cptr = Lcreate_component_instance(componentName);
 
-void Engines_MPIContainer_i::Ascreate_component_instance( const char* componentName,
-                                                         CORBA::Long studyId)
-{
-  Lcreate_component_instance(componentName,studyId);
+  if(_numproc == 0){
+    for(int ip=1;ip<_nbproc;ip++)
+      pthread_join(th[ip],NULL);
+    delete th;
+  }
+
+  return cptr;
 }
 
-Engines::Component_ptr
-Engines_MPIContainer_i::Lcreate_component_instance( const char* genericRegisterName, CORBA::Long studyId)
+Engines::EngineComponent_ptr
+Engines_MPIContainer_i::Lcreate_component_instance( const char* genericRegisterName )
 {
-  if (studyId < 0) {
-    INFOS("studyId must be > 0 for mono study instance, =0 for multiStudy");
-    return Engines::Component::_nil() ;
-  }
-
-  Engines::Component_var iobject = Engines::Component::_nil() ;
+  Engines::EngineComponent_var iobject = Engines::EngineComponent::_nil() ;
   Engines::MPIObject_var pobj;
 
-  string aCompName = genericRegisterName;
+  std::string aCompName = genericRegisterName;
   if (_library_map[aCompName]) { // Python component
     if (_isSupervContainer) {
       INFOS("Supervision Container does not support Python Component Engines");
-      return Engines::Component::_nil();
+      return Engines::EngineComponent::_nil();
     }
     _numInstanceMutex.lock() ; // lock on the instance number
     _numInstance++ ;
@@ -253,26 +264,28 @@ Engines_MPIContainer_i::Lcreate_component_instance( const char* genericRegisterN
 
     char aNumI[12];
     sprintf( aNumI , "%d" , numInstance ) ;
-    string instanceName = aCompName + "_inst_" + aNumI ;
-    string component_registerName =
+    std::string instanceName = aCompName + "_inst_" + aNumI ;
+    std::string component_registerName =
       _containerName + "/" + instanceName;
 
     Py_ACQUIRE_NEW_THREAD;
-    PyObject *mainmod = PyImport_AddModule("__main__");
+    PyObject *mainmod = PyImport_AddModule((char*)"__main__");
     PyObject *globals = PyModule_GetDict(mainmod);
     PyObject *pyCont = PyDict_GetItemString(globals, "pyCont");
     PyObject *result = PyObject_CallMethod(pyCont,
-                                          "create_component_instance",
-                                          "ssl",
-                                          aCompName.c_str(),
-                                          instanceName.c_str(),
-                                          studyId);
-    string iors = PyString_AsString(result);
+                                           (char*)"create_component_instance",
+                                           (char*)"ss",
+                                           aCompName.c_str(),
+                                           instanceName.c_str());
+    const char *ior;
+    const char *error;
+    PyArg_ParseTuple(result,"ss", &ior, &error);
+    std::string iors = ior;
     SCRUTE(iors);
     Py_RELEASE_NEW_THREAD;
   
     CORBA::Object_var obj = _orb->string_to_object(iors.c_str());
-    iobject = Engines::Component::_narrow( obj ) ;
+    iobject = Engines::EngineComponent::_narrow( obj ) ;
     pobj = Engines::MPIObject::_narrow(obj) ;
     if( _numproc == 0 )
       _NS->Register(iobject, component_registerName.c_str()) ;
@@ -284,56 +297,55 @@ Engines_MPIContainer_i::Lcreate_component_instance( const char* genericRegisterN
   
   //--- try C++
 
-  string impl_name = string ("lib") + genericRegisterName +string("Engine.so");
-  void* handle = _library_map[impl_name];
-  if ( !handle ) {
-    INFOS("shared library " << impl_name <<"must be loaded before instance");
-    return Engines::Component::_nil() ;
-  }
-  else {
-    iobject = createMPIInstance(genericRegisterName,
-                               handle,
-                               studyId);
-    return iobject._retn();
-  }
+#ifdef __APPLE__
+  std::string impl_name = std::string ("lib") + genericRegisterName +std::string("Engine.dylib");
+#else
+  std::string impl_name = std::string ("lib") + genericRegisterName +std::string("Engine.so");
+#endif
+  if (_library_map.count(impl_name) != 0) // C++ component
+    {
+      void* handle = _library_map[impl_name];
+      iobject = createMPIInstance(genericRegisterName,
+                                  handle);
+      return iobject._retn();
+    }
+
+  return Engines::EngineComponent::_nil() ;
 }
 
-Engines::Component_ptr
-Engines_MPIContainer_i::createMPIInstance(string genericRegisterName,
-                                         void *handle,
-                                         int studyId)
+Engines::EngineComponent_ptr
+Engines_MPIContainer_i::createMPIInstance(std::string genericRegisterName,
+                                          void *handle)
 {
-  Engines::Component_var iobject;
+  Engines::EngineComponent_var iobject;
   Engines::MPIObject_var pobj;
   // --- find the factory
 
-  string aGenRegisterName = genericRegisterName;
-  string factory_name = aGenRegisterName + string("Engine_factory");
-  SCRUTE(factory_name) ;
+  std::string aGenRegisterName = genericRegisterName;
+  std::string factory_name = aGenRegisterName + std::string("Engine_factory");
 
   typedef  PortableServer::ObjectId * (*MPIFACTORY_FUNCTION)
-    (int,int,
-     CORBA::ORB_ptr,
+    (CORBA::ORB_ptr,
      PortableServer::POA_ptr, 
      PortableServer::ObjectId *, 
      const char *, 
      const char *) ;
 
-  MPIFACTORY_FUNCTION MPIComponent_factory
-    = (MPIFACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
+  dlerror();
+  MPIFACTORY_FUNCTION MPIComponent_factory = (MPIFACTORY_FUNCTION) dlsym(handle, factory_name.c_str());
 
-  char *error ;
-  if ( (error = dlerror() ) != NULL) {
-    // Try to load a sequential component
-    MESSAGE("[" << _numproc << "] Try to load a sequential component");
-    _numInstanceMutex.unlock() ;
-    iobject = Engines_Container_i::createInstance(genericRegisterName,handle,studyId);
-    if( CORBA::is_nil(iobject) ) return Engines::Component::_duplicate(iobject);
-  }
+  if ( !MPIComponent_factory )
+    {
+      INFOS( "[" << _numproc << "] Can't resolve symbol: " + factory_name );
+      SCRUTE( dlerror() );
+      pobj = Engines::MPIObject::_nil();
+      BCastIOR(_orb,pobj,false);
+      return Engines::EngineComponent::_nil();
+    }
 
   // --- create instance
 
-  iobject = Engines::Component::_nil() ;
+  iobject = Engines::EngineComponent::_nil() ;
 
   try
     {
@@ -344,81 +356,76 @@ Engines_MPIContainer_i::createMPIInstance(string genericRegisterName,
 
       char aNumI[12];
       sprintf( aNumI , "%d" , numInstance ) ;
-      string instanceName = aGenRegisterName + "_inst_" + aNumI ;
-      string component_registerName =
-       _containerName + "/" + instanceName;
+      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)
-      id = (MPIComponent_factory) ( _nbproc,_numproc,_orb, _poa, _id, instanceName.c_str(),
-                                aGenRegisterName.c_str() ) ;
+      id = (MPIComponent_factory) ( _orb, _poa, _id, instanceName.c_str(), aGenRegisterName.c_str() ) ;
 
-      // --- 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 ) ;
       pobj = Engines::MPIObject::_narrow(obj) ;
 
-      Engines_Component_i *servant =
-       dynamic_cast<Engines_Component_i*>(_poa->reference_to_servant(iobject));
-      ASSERT(servant);
-      //SCRUTE(servant->pd_refCount);
-      servant->_remove_ref(); // compensate previous id_to_reference 
-      //SCRUTE(servant->pd_refCount);
       _listInstances_map[instanceName] = iobject;
       _cntInstances_map[aGenRegisterName] += 1;
-      SCRUTE(aGenRegisterName);
-      SCRUTE(_cntInstances_map[aGenRegisterName]);
-      //SCRUTE(servant->pd_refCount);
-      bool ret_studyId = servant->setStudyId(studyId);
-      ASSERT(ret_studyId);
 
       // --- register the engine under the name
       //     containerName(.dir)/instanceName(.object)
 
       if( _numproc == 0 ){
-       _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" ) ;
       }
       // Root recupere les ior des composants des autre process
       BCastIOR(_orb,pobj,false);
 
     }
-  catch (...)
-    {
-      INFOS( "Container_i::createInstance exception catched" ) ;
-    }
+  catch(const std::exception &ex){
+    INFOS( ex.what() ) ;
+    return Engines::EngineComponent::_nil();
+  }
   return iobject._retn();
 }
 
 // Load component
-Engines::Component_ptr Engines_MPIContainer_i::load_impl(const char* nameToRegister,
-                                                const char* componentName)
+Engines::EngineComponent_ptr Engines_MPIContainer_i::load_impl(const char* nameToRegister,
+                                                 const char* componentName)
 {
-  if( _numproc == 0 ){
-    // Invocation du chargement du composant dans les autres process
-    for(int ip= 1;ip<_nbproc;ip++)
-      (Engines::MPIContainer::_narrow((*_tior)[ip]))->Asload_impl(nameToRegister,
-                                                               componentName);
+  pthread_t *th = 0;
+  if(_numproc == 0){
+    th = new pthread_t[_nbproc];
+    for(int ip=1;ip<_nbproc;ip++){
+      thread_st *st = new thread_st;
+      st->ip = ip;
+      st->tior = _tior;
+      st->nameToRegister = nameToRegister;
+      st->compoName = componentName;
+      pthread_create(&(th[ip]),NULL,th_loadimpl,(void*)st);
+    }
   }
 
-  return Lload_impl(nameToRegister,componentName);
+  Engines::EngineComponent_ptr cptr =  Lload_impl(nameToRegister,componentName);
 
-}
+  if(_numproc == 0){
+    for(int ip=1;ip<_nbproc;ip++)
+      pthread_join(th[ip],NULL);
+    delete th;
+  }
 
-// Load component
-void Engines_MPIContainer_i::Asload_impl(const char* nameToRegister,
-                                        const char* componentName)
-{
-  Lload_impl(nameToRegister,componentName);
+  return cptr;
 }
 
-Engines::Component_ptr Engines_MPIContainer_i::Lload_impl(
-                                  const char* nameToRegister,
-                                  const char* componentName)
+// Load component
+Engines::EngineComponent_ptr Engines_MPIContainer_i::Lload_impl(
+                                   const char* nameToRegister,
+                                   const char* componentName)
 {
-  Engines::Component_var iobject;
+  Engines::EngineComponent_var iobject;
   Engines::MPIObject_var pobj;
   char cproc[4];
 
@@ -431,35 +438,34 @@ Engines::Component_ptr Engines_MPIContainer_i::Lload_impl(
   char _aNumI[12];
   sprintf(_aNumI,"%d",_numInstance) ;
 
-  string _impl_name = componentName;
-  string _nameToRegister = nameToRegister;
-  string instanceName = _nameToRegister + "_inst_" + _aNumI + cproc;
+  std::string _impl_name = componentName;
+  std::string _nameToRegister = nameToRegister;
+  std::string instanceName = _nameToRegister + "_inst_" + _aNumI + cproc;
   MESSAGE("[" << _numproc << "] instanceName=" << instanceName);
 
-  string absolute_impl_name(_impl_name);
+  std::string absolute_impl_name(_impl_name);
   MESSAGE("[" << _numproc << "] absolute_impl_name=" << absolute_impl_name);
-  void * handle = dlopen(absolute_impl_name.c_str(), RTLD_LAZY);
+  void * handle = dlopen(absolute_impl_name.c_str(), RTLD_LAZY | RTLD_GLOBAL);
   if(!handle){
     INFOS("[" << _numproc << "] Can't load shared library : " << absolute_impl_name);
     INFOS("[" << _numproc << "] error dlopen: " << dlerror());
-    return Engines::Component::_nil() ;
+    return Engines::EngineComponent::_nil() ;
   }
 
-  string factory_name = _nameToRegister + string("Engine_factory");
+  std::string factory_name = _nameToRegister + std::string("Engine_factory");
   MESSAGE("[" << _numproc << "] factory_name=" << factory_name) ;
 
-  PortableServer::ObjectId * (*MPIComponent_factory) (int,int,
-                                                 CORBA::ORB_ptr,
-                                                 PortableServer::POA_ptr,
-                                                 PortableServer::ObjectId *,
-                                                 const char *,
-                                                 const char *) =
-    (PortableServer::ObjectId * (*) (int,int,
-                                    CORBA::ORB_ptr,
-                                    PortableServer::POA_ptr, 
-                                    PortableServer::ObjectId *, 
-                                    const char *, 
-                                    const char *)) 
+  dlerror();
+  PortableServer::ObjectId * (*MPIComponent_factory) (CORBA::ORB_ptr,
+                                                  PortableServer::POA_ptr,
+                                                  PortableServer::ObjectId *,
+                                                  const char *,
+                                                  const char *) =
+    (PortableServer::ObjectId * (*) (CORBA::ORB_ptr,
+                                     PortableServer::POA_ptr, 
+                                     PortableServer::ObjectId *, 
+                                     const char *, 
+                                     const char *)) 
     dlsym(handle, factory_name.c_str());
 
   char *error ;
@@ -468,23 +474,23 @@ Engines::Component_ptr Engines_MPIContainer_i::Lload_impl(
     MESSAGE("[" << _numproc << "] Try to load a sequential component");
     _numInstanceMutex.unlock() ;
     iobject = Engines_Container_i::load_impl(nameToRegister,componentName);
-    if( CORBA::is_nil(iobject) ) return Engines::Component::_duplicate(iobject);
+    if( CORBA::is_nil(iobject) ) return Engines::EngineComponent::_duplicate(iobject);
   }
   else{
     // Instanciation du composant parallele
     MESSAGE("[" << _numproc << "] Try to load a parallel component");
     PortableServer::ObjectId * id = (MPIComponent_factory)
-      (_nbproc,_numproc,_orb, _poa, _id, instanceName.c_str(), _nameToRegister.c_str());
+      (_orb, _poa, _id, instanceName.c_str(), _nameToRegister.c_str());
     // get reference from id
     CORBA::Object_var o = _poa->id_to_reference(*id);
     pobj = Engines::MPIObject::_narrow(o) ;
-    iobject = Engines::Component::_narrow(o) ;
+    iobject = Engines::EngineComponent::_narrow(o) ;
   }
 
   if( _numproc == 0 ){
     // utiliser + tard le registry ici :
     // register the engine under the name containerName.dir/nameToRegister.object
-    string component_registerName = _containerName + "/" + _nameToRegister;
+    std::string component_registerName = _containerName + "/" + _nameToRegister;
     _NS->Register(iobject, component_registerName.c_str()) ;
   }
 
@@ -494,89 +500,118 @@ Engines::Component_ptr Engines_MPIContainer_i::Lload_impl(
   BCastIOR(_orb,pobj,false);
 
   END_OF("[" <<_numproc << "] MPIContainer_i::Lload_impl");
-  return Engines::Component::_duplicate(iobject);
+  return Engines::EngineComponent::_duplicate(iobject);
 
 }
 
-void Engines_MPIContainer_i::remove_impl(Engines::Component_ptr component_i)
+void Engines_MPIContainer_i::remove_impl(Engines::EngineComponent_ptr component_i)
 {
-  int ip;
-  Engines::Component_ptr cptr;
   Engines::MPIObject_ptr pcptr;
   Engines::MPIObject_ptr spcptr;
 
-  ASSERT(! CORBA::is_nil(component_i));
-
-  if( _numproc == 0 ){
-    // Invocation de la destruction du composant dans les autres process
+  pthread_t *th = 0;
+  if(_numproc == 0){
     pcptr = (Engines::MPIObject_ptr)component_i;
-    for(ip= 1;ip<_nbproc;ip++){
+    th = new pthread_t[_nbproc];
+    for(int ip=1;ip<_nbproc;ip++){
+      thread_st *st = new thread_st;
+      st->ip = ip;
+      st->tior = _tior;
       spcptr = Engines::MPIObject::_narrow((*(pcptr->tior()))[ip]);
-      cptr = (Engines::Component_ptr)spcptr;
-      (Engines::MPIContainer::_narrow((*_tior)[ip]))->Asremove_impl(cptr);
+      st->cptr = (Engines::EngineComponent_ptr)spcptr;
+      pthread_create(&(th[ip]),NULL,th_removeimpl,(void*)st);
     }
   }
 
-  Lremove_impl(component_i);
-}
-
-void Engines_MPIContainer_i::Asremove_impl(Engines::Component_ptr component_i)
-{
-  Lremove_impl(component_i);
-}
-
-void Engines_MPIContainer_i::Lremove_impl(Engines::Component_ptr component_i)
-{
-  BEGIN_OF("[" << _numproc << "] MPIContainer_i::Lremove_impl");
-
   ASSERT(! CORBA::is_nil(component_i));
-
-  string instanceName = component_i->instanceName() ;
+  std::string instanceName = component_i->instanceName() ;
   MESSAGE("[" << _numproc << "] unload component " << instanceName);
-  component_i->destroy() ;
-  MESSAGE("[" << _numproc << "] test key handle_map");
   _numInstanceMutex.lock() ; // lock on the remove on handle_map
+  _listInstances_map.erase(instanceName);
   _numInstanceMutex.unlock() ;
-  MESSAGE("[" << _numproc << "] list handle_map");
+  component_i->destroy() ;
+  if(_numproc == 0)
+    _NS->Destroy_Name(instanceName.c_str());
 
-  END_OF("[" << _numproc << "] MPIContainer_i::Lremove_impl");
+  if(_numproc == 0){
+    for(int ip=1;ip<_nbproc;ip++)
+      pthread_join(th[ip],NULL);
+    delete th;
+  }
 
 }
 
 void Engines_MPIContainer_i::finalize_removal()
 {
-  int ip;
+  pthread_t *th = 0;
+  if(_numproc == 0){
+    th = new pthread_t[_nbproc];
+    for(int ip=1;ip<_nbproc;ip++){
+      thread_st *st = new thread_st;
+      st->ip = ip;
+      st->tior = _tior;
+      pthread_create(&(th[ip]),NULL,th_finalizeremoval,(void*)st);
+    }
+  }
 
-  if( _numproc == 0 ){
-    // Invocation de la destruction du composant dans les autres process
-    for(ip= 1;ip<_nbproc;ip++)
-      (Engines::MPIContainer::_narrow((*_tior)[ip]))->Asfinalize_removal();
+  _numInstanceMutex.lock(); // lock to be alone
+  // (see decInstanceCnt, load_component_Library)
+  std::map<std::string, void *>::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);
+    }
   }
+  _toRemove_map.clear();
+  _numInstanceMutex.unlock();
 
-  Lfinalize_removal();
+  if(_numproc == 0){
+    for(int ip=1;ip<_nbproc;ip++)
+      pthread_join(th[ip],NULL);
+    delete th;
+  }
+}
+
+void *th_loadcomponentlibrary(void *s)
+{
+  thread_st *st = (thread_st*)s;
+  char* reason;
+  (Engines::MPIContainer::_narrow((*(st->tior))[st->ip]))->load_component_Library(st->compoName.c_str(),reason);
+  CORBA::string_free(reason);
+  return NULL;
+}
+
+void *th_createcomponentinstance(void *s)
+{
+  thread_st *st = (thread_st*)s;
+  (Engines::MPIContainer::_narrow((*(st->tior))[st->ip]))->create_component_instance(st->compoName.c_str());
+  return NULL;
+}
+
+void *th_loadimpl(void *s)
+{
+  thread_st *st = (thread_st*)s;
+  (Engines::MPIContainer::_narrow((*(st->tior))[st->ip]))->load_impl(st->nameToRegister.c_str(),st->compoName.c_str());
+  return NULL;
 }
 
-void Engines_MPIContainer_i::Asfinalize_removal()
+void *th_removeimpl(void *s)
 {
-  Lfinalize_removal();
+  thread_st *st = (thread_st*)s;
+  (Engines::MPIContainer::_narrow((*(st->tior))[st->ip]))->remove_impl(st->cptr);
+  return NULL;
 }
 
-void Engines_MPIContainer_i::Lfinalize_removal()
+void *th_finalizeremoval(void *s)
 {
-  BEGIN_OF("[" << _numproc << "] MPIContainer_i::Lfinalize_removal");
-
-//   map<string, void *>::iterator im ;
-//   // lock on the explore remove_map & dlclose
-//   _numInstanceMutex.lock() ; 
-//   for (im = remove_map.begin() ; im != remove_map.end() ; im ++)
-//     {
-//       void * handle = (*im).second ;
-//       MESSAGE("[" << _numproc << "] dlclose " << (*im).first);
-//       dlclose(handle) ;
-//     }
-//   MESSAGE("[" << _numproc << "] remove_map.clear()");
-//   remove_map.clear() ;  
-//   _numInstanceMutex.unlock() ;
-
-  END_OF("[" << _numproc << "] MPIContainer_i::Lfinalize_removal");
+  thread_st *st = (thread_st*)s;
+  (Engines::MPIContainer::_narrow((*(st->tior))[st->ip]))->finalize_removal();
+  return NULL;
 }