Salome HOME
Merge branch 'rbe/evol-job-newparams'
authorRenaud Barate <renaud.barate@edf.fr>
Wed, 8 Oct 2014 15:56:04 +0000 (17:56 +0200)
committerRenaud Barate <renaud.barate@edf.fr>
Wed, 8 Oct 2014 15:56:04 +0000 (17:56 +0200)
* rbe/evol-job-newparams:
  Fix bug when creating JobParameters in Python (due to previous evolutions)
  SALOME Launcher: add possibility to specify extra parameters
  Add batch parameter wckey to SALOME Launcher

13 files changed:
bin/ORBConfigFile.py
idl/SALOME_PyNode.idl
src/Basics/Basics_Utils.cxx
src/Container/SALOME_ContainerManager.cxx
src/Container/SALOME_ContainerManager.hxx
src/Container/SALOME_PyNode.py
src/NamingService/SALOME_NamingService.cxx
src/NamingService/SALOME_NamingService.hxx
src/ResourcesManager/ResourcesManager.cxx
src/ResourcesManager/ResourcesManager.hxx
src/ResourcesManager/SALOME_LoadRateManager.cxx
src/ResourcesManager/SALOME_LoadRateManager.hxx
src/ResourcesManager/SALOME_ResourcesManager.cxx

index a80c723b669eb957e69f63d888a7020969ee7fec..02bdf59a4ba57b199d6c0ec5293b336377b392f8 100644 (file)
@@ -46,6 +46,7 @@ def writeORBConfigFile(path, host, port, kwargs={}):
   orbdata.append("%sInitRef = NameService=corbaname::%s:%s"%(prefix,host,port))
   orbdata.append("%sgiopMaxMsgSize = %s # 2 GBytes"%(prefix,GIOP_MaxMsgSize))
   orbdata.append("%straceLevel = 0 # critical errors only"%(prefix))
+  orbdata.append("%smaxGIOPConnectionPerServer = 50 # to allow containers parallel launch"%(prefix))
   orbdata.append("")
 
   f = open(omniorb_config, "w")
index ba3bfaadb665a60a2b15c2d328c6eaa9da97f6e6..5faf372ac3ca3438794f0386f38fea947a8ffbb5 100644 (file)
@@ -61,6 +61,13 @@ module Engines
 
   interface PyScriptNode : PyNodeBase
   {
+    /*!
+      This method compiles, but NOT EXECUTE, the code \a codeStr. The result of the compiled code will be used then
+      on execute step.
+      \param codeStr - the python code (without statement) to be executed, that can modify the context initialized at initialization.
+     */
+    void assignNewCompiledCode(in string codeStr) raises (SALOME::SALOME_Exception);
+
     /*! \brief execute a python script defined in the node
 
       \param outargsname output argument names 
index 1238db6ecdcd72988a36255088420fc09e408cae..c52291cf48fee40f04db7d112dc9bc0d10196e41 100644 (file)
@@ -35,6 +35,7 @@
 
 namespace Kernel_Utils
 {
+  // threadsafe
   std::string GetHostname()
   {
     int ls = 100, r = 1;
@@ -44,7 +45,7 @@ namespace Kernel_Utils
       {
         ls *= 2;
         s = new char[ls];
-        r = gethostname(s, ls-1);
+        r = gethostname(s, ls-1);//threadsafe see man 7 pthread
         switch (r) 
           {
           case 0:
index 26febd3d26c56c8470943ef770669100adafe10c..8a33c0fec0ff6711f252c1480ebef3ead3b9976e 100644 (file)
@@ -55,6 +55,9 @@ const char *SALOME_ContainerManager::_ContainerManagerNameInNS =
 
 omni_mutex SALOME_ContainerManager::_numInstanceMutex;
 
+Utils_Mutex SALOME_ContainerManager::_getenvMutex;
+
+Utils_Mutex SALOME_ContainerManager::_systemMutex;
 
 //=============================================================================
 /*! 
@@ -75,11 +78,10 @@ SALOME_ContainerManager::SALOME_ContainerManager(CORBA::ORB_ptr orb, PortableSer
   _orb = CORBA::ORB::_duplicate(orb) ;
   CORBA::PolicyList policies;
   policies.length(1);
-  PortableServer::ThreadPolicy_var threadPol = 
-    poa->create_thread_policy(PortableServer::SINGLE_THREAD_MODEL);
+  PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::ORB_CTRL_MODEL));
   policies[0] = PortableServer::ThreadPolicy::_duplicate(threadPol);
 
-  _poa = poa->create_POA("SThreadPOA",pman,policies);
+  _poa = poa->create_POA("MThreadPOA",pman,policies);
   threadPol->destroy();
   PortableServer::ObjectId_var id = _poa->activate_object(this);
   CORBA::Object_var obj = _poa->id_to_reference(id);
@@ -87,23 +89,23 @@ SALOME_ContainerManager::SALOME_ContainerManager(CORBA::ORB_ptr orb, PortableSer
     Engines::ContainerManager::_narrow(obj);
 
   _NS->Register(refContMan,_ContainerManagerNameInNS);
-  _isAppliSalomeDefined = (getenv("APPLI") != 0);
+  _isAppliSalomeDefined = (GetenvThreadSafe("APPLI") != 0);
 
 #ifdef HAVE_MPI2
 #ifdef WITHOPENMPI
   _pid_mpiServer = -1;
   // the urifile name depends on pid of the process
   std::stringstream urifile;
-  urifile << getenv("HOME") << "/.urifile_" << getpid();
+  urifile << GetenvThreadSafe("HOME") << "/.urifile_" << getpid();
   setenv("OMPI_URI_FILE",urifile.str().c_str(),1);
-  if( getenv("OMPI_URI_FILE") != NULL ){
+  if( GetenvThreadSafe("OMPI_URI_FILE") != NULL ){
     // get the pid of all ompi-server
     std::set<pid_t> thepids1 = getpidofprogram("ompi-server");
     // launch a new ompi-server
     std::string command;
     command = "ompi-server -r ";
-    command += getenv("OMPI_URI_FILE");
-    int status=system(command.c_str());
+    command += GetenvThreadSafe("OMPI_URI_FILE");
+    int status=SystemThreadSafe(command.c_str());
     if(status!=0)
       throw SALOME_Exception("Error when launching ompi-server");
     // get the pid of all ompi-server
@@ -123,7 +125,7 @@ SALOME_ContainerManager::SALOME_ContainerManager(CORBA::ORB_ptr orb, PortableSer
   // launch a new hydra_nameserver
   std::string command;
   command = "hydra_nameserver &";
-  system(command.c_str());
+  SystemThreadSafe(command.c_str());
   // get the pid of all hydra_nameserver
   std::set<pid_t> thepids2 = getpidofprogram("hydra_nameserver");
   // my hydra_nameserver is the new one
@@ -148,12 +150,12 @@ SALOME_ContainerManager::~SALOME_ContainerManager()
   MESSAGE("destructor");
 #ifdef HAVE_MPI2
 #ifdef WITHOPENMPI
-  if( getenv("OMPI_URI_FILE") != NULL ){
+  if( GetenvThreadSafe("OMPI_URI_FILE") != NULL ){
     // kill my ompi-server
     if( kill(_pid_mpiServer,SIGTERM) != 0 )
       throw SALOME_Exception("Error when killing ompi-server");
     // delete my urifile
-    int status=system("rm -f ${OMPI_URI_FILE}");
+    int status=SystemThreadSafe("rm -f ${OMPI_URI_FILE}");
     if(status!=0)
       throw SALOME_Exception("Error when removing urifile");
   }
@@ -263,11 +265,10 @@ void SALOME_ContainerManager::ShutdownContainers()
  *  \return the container or nil
  */
 //=============================================================================
-Engines::Container_ptr
-SALOME_ContainerManager::GiveContainer(const Engines::ContainerParameters& params)
+Engines::Container_ptr SALOME_ContainerManager::GiveContainer(const Engines::ContainerParameters& params)
 {
   std::string machFile;
-  Engines::Container_ptr ret = Engines::Container::_nil();
+  Engines::Container_ptr ret(Engines::Container::_nil());
 
   // Step 0: Default mode is start
   Engines::ContainerParameters local_params(params);
@@ -369,7 +370,7 @@ SALOME_ContainerManager::GiveContainer(const Engines::ContainerParameters& param
           nbproc = params.nb_proc;
         try
         {
-          if( getenv("LIBBATCH_NODEFILE") != NULL )
+          if( GetenvThreadSafe("LIBBATCH_NODEFILE") != NULL )
             machFile = machinesFile(nbproc);
         }
         catch(const SALOME_Exception & ex)
@@ -389,29 +390,33 @@ SALOME_ContainerManager::GiveContainer(const Engines::ContainerParameters& param
       // Step 6: check if the name exists in naming service
       //if params.mode == "getorstart" or "get" use the existing container
       //if params.mode == "start" shutdown the existing container before launching a new one with that name
-      CORBA::Object_var obj = _NS->Resolve(containerNameInNS.c_str());
-      if (!CORBA::is_nil(obj))
-      {
-        try
-        {
-          Engines::Container_var cont=Engines::Container::_narrow(obj);
-          if(!cont->_non_existent())
+
+      { // critical section
+        Utils_Locker lock (&_giveContainerMutex1);
+        CORBA::Object_var obj = _NS->Resolve(containerNameInNS.c_str());
+        if (!CORBA::is_nil(obj))
           {
-            if(std::string(params.mode.in())=="getorstart" || std::string(params.mode.in())=="get"){
-              return cont._retn(); /* the container exists and params.mode is getorstart or get use it*/
+            try
+            {
+                Engines::Container_var cont=Engines::Container::_narrow(obj);
+                if(!cont->_non_existent())
+                  {
+                    if(std::string(params.mode.in())=="getorstart" || std::string(params.mode.in())=="get"){
+                        return cont._retn(); /* the container exists and params.mode is getorstart or get use it*/
+                    }
+                    else
+                      {
+                        INFOS("[GiveContainer] A container is already registered with the name: " << containerNameInNS << ", shutdown the existing container");
+                        cont->Shutdown(); // shutdown the registered container if it exists
+                      }
+                  }
             }
-            else
+            catch(CORBA::Exception&)
             {
-              INFOS("[GiveContainer] A container is already registered with the name: " << containerNameInNS << ", shutdown the existing container");
-              cont->Shutdown(); // shutdown the registered container if it exists
+                INFOS("[GiveContainer] CORBA::Exception ignored when trying to get the container - we start a new one");
             }
           }
-        }
-        catch(CORBA::Exception&)
-        {
-          INFOS("[GiveContainer] CORBA::Exception ignored when trying to get the container - we start a new one");
-        }
-      }
+      } // end critical section
       Engines::Container_var cont = LaunchContainer(params, resource_selected, hostname, machFile, containerNameInNS);
       if (!CORBA::is_nil(cont))
       {
@@ -440,221 +445,222 @@ SALOME_ContainerManager::LaunchContainer(const Engines::ContainerParameters& par
                                          const std::string & machFile,
                                          const std::string & containerNameInNS)
 {
-
-  // Step 1: type of container: PaCO, Exe, Mpi or Classic
-  // Mpi already tested in step 5, specific code on BuildCommandToLaunch Local/Remote Container methods
-  // TODO -> separates Mpi from Classic/Exe
-  // Classic or Exe ?
-  std::string container_exe = "SALOME_Container"; // Classic container
-  Engines::ContainerParameters local_params(params);
-  Engines::Container_ptr ret = Engines::Container::_nil();
-  int found=0;
-  try
-  {
-    CORBA::String_var container_exe_tmp;
-    CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog");
-    SALOME_ModuleCatalog::ModuleCatalog_var Catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
-    if (CORBA::is_nil (Catalog))
+  std::string user,command,logFilename,tmpFileName;
+  int status;
+  Engines::Container_ptr ret(Engines::Container::_nil());
+  {//start of critical section
+    Utils_Locker lock (&_giveContainerMutex1);
+    // Step 1: type of container: PaCO, Exe, Mpi or Classic
+    // Mpi already tested in step 5, specific code on BuildCommandToLaunch Local/Remote Container methods
+    // TODO -> separates Mpi from Classic/Exe
+    // Classic or Exe ?
+    std::string container_exe = "SALOME_Container"; // Classic container
+    Engines::ContainerParameters local_params(params);
+    int found=0;
+    try
     {
-      INFOS("[GiveContainer] Module Catalog is not found -> cannot launch a container");
-      return ret;
+        CORBA::String_var container_exe_tmp;
+        CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog");
+        SALOME_ModuleCatalog::ModuleCatalog_var Catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
+        if (CORBA::is_nil (Catalog))
+          {
+            INFOS("[GiveContainer] Module Catalog is not found -> cannot launch a container");
+            return ret;
+          }
+        // Loop through component list
+        for(unsigned int i=0; i < local_params.resource_params.componentList.length(); i++)
+          {
+            const char* compoi = local_params.resource_params.componentList[i];
+            SALOME_ModuleCatalog::Acomponent_var compoInfo = Catalog->GetComponent(compoi);
+            if (CORBA::is_nil (compoInfo))
+              {
+                continue;
+              }
+            SALOME_ModuleCatalog::ImplType impl=compoInfo->implementation_type();
+            container_exe_tmp=compoInfo->implementation_name();
+            if(impl==SALOME_ModuleCatalog::CEXE)
+              {
+                if(found)
+                  {
+                    INFOS("ContainerManager Error: you can't have 2 CEXE component in the same container" );
+                    return Engines::Container::_nil();
+                  }
+                MESSAGE("[GiveContainer] Exe container found !: " << container_exe_tmp);
+                container_exe = container_exe_tmp.in();
+                found=1;
+              }
+          }
     }
-    // Loop through component list
-    for(unsigned int i=0; i < local_params.resource_params.componentList.length(); i++)
+    catch (ServiceUnreachable&)
     {
-      const char* compoi = local_params.resource_params.componentList[i];
-      SALOME_ModuleCatalog::Acomponent_var compoInfo = Catalog->GetComponent(compoi);
-      if (CORBA::is_nil (compoInfo))
-      {
-        continue;
-      }
-      SALOME_ModuleCatalog::ImplType impl=compoInfo->implementation_type();
-      container_exe_tmp=compoInfo->implementation_name();
-      if(impl==SALOME_ModuleCatalog::CEXE)
-      {
-        if(found)
-        {
-          INFOS("ContainerManager Error: you can't have 2 CEXE component in the same container" );
-          return Engines::Container::_nil();
-        }
-        MESSAGE("[GiveContainer] Exe container found !: " << container_exe_tmp);
-        container_exe = container_exe_tmp.in();
-        found=1;
-      }
+        INFOS("Caught exception: Naming Service Unreachable");
+        return ret;
     }
-  }
-  catch (ServiceUnreachable&)
-  {
-    INFOS("Caught exception: Naming Service Unreachable");
-    return ret;
-  }
-  catch (...)
-  {
-    INFOS("Caught unknown exception.");
-    return ret;
-  }
-
-  // Step 2: test resource
-  // Only if an application directory is set
-  if(hostname != Kernel_Utils::GetHostname() && _isAppliSalomeDefined)
-  {
-    // Preparing remote command
-    std::string command = "";
-    const ParserResourcesType& resInfo = _ResManager->GetImpl()->GetResourcesDescr(resource_selected);
-    command = getCommandToRunRemoteProcess(resInfo.Protocol, resInfo.HostName, resInfo.UserName);
-    if (resInfo.AppliPath != "")
-      command += resInfo.AppliPath;
-    else
+    catch (...)
     {
-      ASSERT(getenv("APPLI"));
-      command += getenv("APPLI");
+        INFOS("Caught unknown exception.");
+        return ret;
     }
-    command += "/runRemote.sh ";
-    ASSERT(getenv("NSHOST")); 
-    command += getenv("NSHOST"); // hostname of CORBA name server
-    command += " ";
-    ASSERT(getenv("NSPORT"));
-    command += getenv("NSPORT"); // port of CORBA name server
-    command += " \"ls /tmp >/dev/null 2>&1\"";
 
-    // Launch remote command
-    int status = system(command.c_str());
-    if (status != 0)
-    {
-      // Error on resource - cannot launch commands
-      INFOS("[LaunchContainer] Cannot launch commands on machine " << hostname);
-      INFOS("[LaunchContainer] Command was " << command);
+    // Step 2: test resource
+    // Only if an application directory is set
+    if(hostname != Kernel_Utils::GetHostname() && _isAppliSalomeDefined)
+      {
+        // Preparing remote command
+        std::string command = "";
+        const ParserResourcesType resInfo(_ResManager->GetImpl()->GetResourcesDescr(resource_selected));
+        command = getCommandToRunRemoteProcess(resInfo.Protocol, resInfo.HostName, resInfo.UserName);
+        if (resInfo.AppliPath != "")
+          command += resInfo.AppliPath;
+        else
+          {
+            ASSERT(GetenvThreadSafe("APPLI"));
+            command += GetenvThreadSafe("APPLI");
+          }
+        command += "/runRemote.sh ";
+        ASSERT(GetenvThreadSafe("NSHOST"));
+        command += GetenvThreadSafe("NSHOST"); // hostname of CORBA name server
+        command += " ";
+        ASSERT(GetenvThreadSafe("NSPORT"));
+        command += GetenvThreadSafe("NSPORT"); // port of CORBA name server
+        command += " \"ls /tmp >/dev/null 2>&1\"";
+
+        // Launch remote command
+        int status = SystemThreadSafe(command.c_str());
+        if (status != 0)
+          {
+            // Error on resource - cannot launch commands
+            INFOS("[LaunchContainer] Cannot launch commands on machine " << hostname);
+            INFOS("[LaunchContainer] Command was " << command);
 #ifndef WIN32
-      INFOS("[LaunchContainer] Command status is " << WEXITSTATUS(status));
+            INFOS("[LaunchContainer] Command status is " << WEXITSTATUS(status));
 #endif
-      return Engines::Container::_nil();
-    }
-  }
+            return Engines::Container::_nil();
+          }
+      }
 
-  // Step 3: start a new container
-  // Check if a PaCO container
-  // PaCO++
-  if (std::string(local_params.parallelLib.in()) != "")
-  {
-    ret = StartPaCOPPContainer(params, resource_selected);
-    return ret;
-  }
-  // Other type of containers...
-  MESSAGE("[GiveContainer] Try to launch a new container on " << resource_selected);
-  std::string command;
-  // if a parallel container is launched in batch job, command is: "mpirun -np nbproc -machinefile nodesfile SALOME_MPIContainer"
-  if( getenv("LIBBATCH_NODEFILE") != NULL && params.isMPI )
-    command = BuildCommandToLaunchLocalContainer(params, machFile, container_exe);
-  // if a container is launched on localhost, command is "SALOME_Container" or "mpirun -np nbproc SALOME_MPIContainer"
-  else if(hostname == Kernel_Utils::GetHostname())
-    command = BuildCommandToLaunchLocalContainer(params, machFile, container_exe);
-  // if a container is launched in remote mode, command is "ssh resource_selected SALOME_Container" or "ssh resource_selected mpirun -np nbproc SALOME_MPIContainer"
-  else
-    command = BuildCommandToLaunchRemoteContainer(resource_selected, params, container_exe);
+    // Step 3: start a new container
+    // Check if a PaCO container
+    // PaCO++
+    if (std::string(local_params.parallelLib.in()) != "")
+      {
+        ret = StartPaCOPPContainer(params, resource_selected);
+        return ret;
+      }
+    // Other type of containers...
+    MESSAGE("[GiveContainer] Try to launch a new container on " << resource_selected);
+    // if a parallel container is launched in batch job, command is: "mpirun -np nbproc -machinefile nodesfile SALOME_MPIContainer"
+    if( GetenvThreadSafe("LIBBATCH_NODEFILE") != NULL && params.isMPI )
+      command = BuildCommandToLaunchLocalContainer(params, machFile, container_exe, tmpFileName);
+    // if a container is launched on localhost, command is "SALOME_Container" or "mpirun -np nbproc SALOME_MPIContainer"
+    else if(hostname == Kernel_Utils::GetHostname())
+      command = BuildCommandToLaunchLocalContainer(params, machFile, container_exe, tmpFileName);
+    // if a container is launched in remote mode, command is "ssh resource_selected SALOME_Container" or "ssh resource_selected mpirun -np nbproc SALOME_MPIContainer"
+    else
+      command = BuildCommandToLaunchRemoteContainer(resource_selected, params, container_exe);
 
-  //redirect stdout and stderr in a file
+    //redirect stdout and stderr in a file
 #ifdef WIN32
-  std::string logFilename=getenv("TEMP");
-  logFilename += "\\";
-  std::string user = getenv( "USERNAME" );
+    logFilename=GetenvThreadSafe("TEMP");
+    logFilename += "\\";
+    user = GetenvThreadSafe( "USERNAME" );
 #else
-  std::string user = getenv( "USER" );
-  std::string logFilename="/tmp";
-  char* val = getenv("SALOME_TMP_DIR");
-  if(val)
-  {
-    struct stat file_info;
-    stat(val, &file_info);
-    bool is_dir = S_ISDIR(file_info.st_mode);
-    if (is_dir)logFilename=val;
-    else std::cerr << "SALOME_TMP_DIR environment variable is not a directory use /tmp instead" << std::endl;
-  }
-  logFilename += "/";
+    user = GetenvThreadSafe( "USER" );
+    logFilename="/tmp";
+    char* val = GetenvThreadSafe("SALOME_TMP_DIR");
+    if(val)
+      {
+        struct stat file_info;
+        stat(val, &file_info);
+        bool is_dir = S_ISDIR(file_info.st_mode);
+        if (is_dir)logFilename=val;
+        else std::cerr << "SALOME_TMP_DIR environment variable is not a directory use /tmp instead" << std::endl;
+      }
+    logFilename += "/";
 #endif
-  logFilename += _NS->ContainerName(params)+"_"+ resource_selected +"_"+user;
-  std::ostringstream tmp;
-  tmp << "_" << getpid();
-  logFilename += tmp.str();
-  logFilename += ".log" ;
-  command += " > " + logFilename + " 2>&1";
+    logFilename += _NS->ContainerName(params)+"_"+ resource_selected +"_"+user;
+    std::ostringstream tmp;
+    tmp << "_" << getpid();
+    logFilename += tmp.str();
+    logFilename += ".log" ;
+    command += " > " + logFilename + " 2>&1";
 #ifdef WIN32
-  command = "%PYTHONBIN% -c \"import win32pm ; win32pm.spawnpid(r'" + command + "', '')\"";
+    command = "%PYTHONBIN% -c \"import win32pm ; win32pm.spawnpid(r'" + command + "', '')\"";
 #else
-  command += " &";
+    command += " &";
 #endif
 
-  // launch container with a system call
-  int status=system(command.c_str());
+    // launch container with a system call
+    status=SystemThreadSafe(command.c_str());
+  }//end of critical of section
 
-  if (status == -1){
-    INFOS("[LaunchContainer] command failed (system command status -1): " << command);
-    RmTmpFile(_TmpFileName); // command file can be removed here
-    _TmpFileName="";
-    return Engines::Container::_nil();
-  }
-  else if (status == 217){
-    INFOS("[LaunchContainer] command failed (system command status 217): " << command);
-    RmTmpFile(_TmpFileName); // command file can be removed here
-    _TmpFileName="";
-    return Engines::Container::_nil();
-  }
-  else
-  {
-    // Step 4: Wait for the container
-    int count = TIME_OUT_TO_LAUNCH_CONT;
-    if (getenv("TIMEOUT_TO_LAUNCH_CONTAINER") != 0)
+  if (status == -1)
     {
-      std::string new_count_str = getenv("TIMEOUT_TO_LAUNCH_CONTAINER");
-      int new_count;
-      std::istringstream ss(new_count_str);
-      if (!(ss >> new_count))
-      {
-        INFOS("[LaunchContainer] TIMEOUT_TO_LAUNCH_CONTAINER should be an int");
-      }
-      else
-        count = new_count;
+      INFOS("[LaunchContainer] command failed (system command status -1): " << command);
+      RmTmpFile(tmpFileName); // command file can be removed here
+      return Engines::Container::_nil();
     }
-    INFOS("[GiveContainer] waiting " << count << " second steps container " << containerNameInNS);
-    while (CORBA::is_nil(ret) && count)
+  else if (status == 217)
+    {
+      INFOS("[LaunchContainer] command failed (system command status 217): " << command);
+      RmTmpFile(tmpFileName); // command file can be removed here
+      return Engines::Container::_nil();
+    }
+  else
     {
+      // Step 4: Wait for the container
+      int count = TIME_OUT_TO_LAUNCH_CONT;
+      if (GetenvThreadSafe("TIMEOUT_TO_LAUNCH_CONTAINER") != 0)
+        {
+          std::string new_count_str = GetenvThreadSafe("TIMEOUT_TO_LAUNCH_CONTAINER");
+          int new_count;
+          std::istringstream ss(new_count_str);
+          if (!(ss >> new_count))
+            {
+              INFOS("[LaunchContainer] TIMEOUT_TO_LAUNCH_CONTAINER should be an int");
+            }
+          else
+            count = new_count;
+        }
+      INFOS("[GiveContainer] waiting " << count << " second steps container " << containerNameInNS);
+      while (CORBA::is_nil(ret) && count)
+        {
 #ifndef WIN32
-      sleep( 1 ) ;
+          sleep( 1 ) ;
 #else
-      Sleep(1000);
+          Sleep(1000);
 #endif
-      count--;
-      MESSAGE("[GiveContainer] step " << count << " Waiting for container on " << resource_selected);
-      CORBA::Object_var obj = _NS->Resolve(containerNameInNS.c_str());
-      ret=Engines::Container::_narrow(obj);
-    }
-    if (CORBA::is_nil(ret))
-    {
-      INFOS("[GiveContainer] was not able to launch container " << containerNameInNS);
-    }
-    else
-    {
-      // Setting log file name
-      logFilename=":"+logFilename;
-      logFilename="@"+Kernel_Utils::GetHostname()+logFilename;
-      logFilename=user+logFilename;
-      ret->logfilename(logFilename.c_str());
-      RmTmpFile(_TmpFileName); // command file can be removed here
-      _TmpFileName="";
+          count--;
+          MESSAGE("[GiveContainer] step " << count << " Waiting for container on " << resource_selected);
+          CORBA::Object_var obj = _NS->Resolve(containerNameInNS.c_str());
+          ret=Engines::Container::_narrow(obj);
+        }
+      if (CORBA::is_nil(ret))
+        {
+          INFOS("[GiveContainer] was not able to launch container " << containerNameInNS);
+        }
+      else
+        {
+          // Setting log file name
+          logFilename=":"+logFilename;
+          logFilename="@"+Kernel_Utils::GetHostname()+logFilename;//threadsafe
+          logFilename=user+logFilename;
+          ret->logfilename(logFilename.c_str());
+          RmTmpFile(tmpFileName); // command file can be removed here
+        }
     }
-  }
   return ret;
 }
 
 //=============================================================================
 //! Find a container given constraints (params) on a list of machines (possibleComputers)
+//! agy : this method is ThreadSafe
 /*!
  *
  */
 //=============================================================================
 
-Engines::Container_ptr
-SALOME_ContainerManager::FindContainer(const Engines::ContainerParameters& params,
-                                       const Engines::ResourceList& possibleResources)
+Engines::Container_ptr SALOME_ContainerManager::FindContainer(const Engines::ContainerParameters& params, const Engines::ResourceList& possibleResources)
 {
   MESSAGE("[FindContainer] FindContainer on " << possibleResources.length() << " resources");
   for(unsigned int i=0; i < possibleResources.length();i++)
@@ -669,14 +675,14 @@ SALOME_ContainerManager::FindContainer(const Engines::ContainerParameters& param
 
 //=============================================================================
 //! Find a container given constraints (params) on a machine (theMachine)
+//! agy : this method is ThreadSafe
 /*!
  *
  */
 //=============================================================================
 
 Engines::Container_ptr
-SALOME_ContainerManager::FindContainer(const Engines::ContainerParameters& params,
-                                       const std::string& resource)
+SALOME_ContainerManager::FindContainer(const Engines::ContainerParameters& params, const std::string& resource)
 {
   Engines::ResourceDefinition_var resource_definition = _ResManager->GetResourceDefinition(resource.c_str());
   std::string hostname(resource_definition->hostname.in());
@@ -741,20 +747,17 @@ bool isPythonContainer(const char* ContainerName)
 //=============================================================================
 
 std::string
-SALOME_ContainerManager::BuildCommandToLaunchRemoteContainer
-(const std::string& resource_name,
- const Engines::ContainerParameters& params, const std::string& container_exe)
+SALOME_ContainerManager::BuildCommandToLaunchRemoteContainer(const std::string& resource_name, const Engines::ContainerParameters& params, const std::string& container_exe) const
 {
-
-  std::string command;
+  std::string command,tmpFileName;
   if (!_isAppliSalomeDefined)
-    command = BuildTempFileToLaunchRemoteContainer(resource_name, params);
+    command = BuildTempFileToLaunchRemoteContainer(resource_name, params, tmpFileName);
   else
   {
     int nbproc;
     Engines::ResourceDefinition_var resource_definition = _ResManager->GetResourceDefinition(resource_name.c_str());
     std::string hostname(resource_definition->hostname.in());
-    const ParserResourcesType& resInfo = _ResManager->GetImpl()->GetResourcesDescr(resource_name);
+    const ParserResourcesType resInfo(_ResManager->GetImpl()->GetResourcesDescr(resource_name));
 
     if (params.isMPI)
     {
@@ -772,18 +775,18 @@ SALOME_ContainerManager::BuildCommandToLaunchRemoteContainer
       command += resInfo.AppliPath; // path relative to user@machine $HOME
     else
     {
-      ASSERT(getenv("APPLI"));
-      command += getenv("APPLI"); // path relative to user@machine $HOME
+      ASSERT(GetenvThreadSafe("APPLI"));
+      command += GetenvThreadSafe("APPLI"); // path relative to user@machine $HOME
     }
 
     command += "/runRemote.sh ";
 
-    ASSERT(getenv("NSHOST")); 
-    command += getenv("NSHOST"); // hostname of CORBA name server
+    ASSERT(GetenvThreadSafe("NSHOST"));
+    command += GetenvThreadSafe("NSHOST"); // hostname of CORBA name server
 
     command += " ";
-    ASSERT(getenv("NSPORT"));
-    command += getenv("NSPORT"); // port of CORBA name server
+    ASSERT(GetenvThreadSafe("NSPORT"));
+    command += GetenvThreadSafe("NSPORT"); // port of CORBA name server
 
     std::string wdir = params.workingdir.in();
     if(wdir != "")
@@ -805,11 +808,11 @@ SALOME_ContainerManager::BuildCommandToLaunchRemoteContainer
 #ifdef WITHLAM
       command += "-x PATH,LD_LIBRARY_PATH,OMNIORB_CONFIG,SALOME_trace ";
 #elif defined(WITHOPENMPI)
-      if( getenv("OMPI_URI_FILE") == NULL )
+      if( GetenvThreadSafe("OMPI_URI_FILE") == NULL )
         command += "-x PATH -x LD_LIBRARY_PATH -x OMNIORB_CONFIG -x SALOME_trace";
       else{
         command += "-x PATH -x LD_LIBRARY_PATH -x OMNIORB_CONFIG -x SALOME_trace -ompi-server file:";
-        command += getenv("OMPI_URI_FILE");
+        command += GetenvThreadSafe("OMPI_URI_FILE");
       }
 #elif defined(WITHMPICH)
       command += "-nameserver " + Kernel_Utils::GetHostname();
@@ -834,11 +837,9 @@ SALOME_ContainerManager::BuildCommandToLaunchRemoteContainer
  *  builds the command to be launched.
  */ 
 //=============================================================================
-std::string
-SALOME_ContainerManager::BuildCommandToLaunchLocalContainer
-(const Engines::ContainerParameters& params, const std::string& machinesFile, const std::string& container_exe)
+std::string SALOME_ContainerManager::BuildCommandToLaunchLocalContainer(const Engines::ContainerParameters& params, const std::string& machinesFile, const std::string& container_exe, std::string& tmpFileName) const
 {
-  _TmpFileName = BuildTemporaryFileName();
+  tmpFileName = BuildTemporaryFileName();
   std::string command;
   int nbproc = 0;
 
@@ -855,18 +856,18 @@ SALOME_ContainerManager::BuildCommandToLaunchLocalContainer
 
       o << nbproc << " ";
 
-      if( getenv("LIBBATCH_NODEFILE") != NULL )
+      if( GetenvThreadSafe("LIBBATCH_NODEFILE") != NULL )
         o << "-machinefile " << machinesFile << " ";
 
 #ifdef WITHLAM
       o << "-x PATH,LD_LIBRARY_PATH,OMNIORB_CONFIG,SALOME_trace ";
 #elif defined(WITHOPENMPI)
-      if( getenv("OMPI_URI_FILE") == NULL )
+      if( GetenvThreadSafe("OMPI_URI_FILE") == NULL )
         o << "-x PATH -x LD_LIBRARY_PATH -x OMNIORB_CONFIG -x SALOME_trace";
       else
         {
           o << "-x PATH -x LD_LIBRARY_PATH -x OMNIORB_CONFIG -x SALOME_trace -ompi-server file:";
-          o << getenv("OMPI_URI_FILE");
+          o << GetenvThreadSafe("OMPI_URI_FILE");
         }
 #elif defined(WITHMPICH)
       o << "-nameserver " + Kernel_Utils::GetHostname();
@@ -918,14 +919,14 @@ SALOME_ContainerManager::BuildCommandToLaunchLocalContainer
   o << " -";
   AddOmninamesParams(o);
 
-  std::ofstream command_file( _TmpFileName.c_str() );
+  std::ofstream command_file( tmpFileName.c_str() );
   command_file << o.str();
   command_file.close();
 
 #ifndef WIN32
-  chmod(_TmpFileName.c_str(), 0x1ED);
+  chmod(tmpFileName.c_str(), 0x1ED);
 #endif
-  command = _TmpFileName;
+  command = tmpFileName;
 
   MESSAGE("Command is file ... " << command);
   MESSAGE("Command is ... " << o.str());
@@ -936,6 +937,7 @@ SALOME_ContainerManager::BuildCommandToLaunchLocalContainer
 //=============================================================================
 /*!
  *  removes the generated temporary file in case of a remote launch.
+ *  This method is thread safe
  */ 
 //=============================================================================
 
@@ -954,7 +956,7 @@ void SALOME_ContainerManager::RmTmpFile(std::string& tmpFileName)
       else
         command += tmpFileName;
       command += '*';
-      system(command.c_str());
+      SystemThreadSafe(command.c_str());
       //if dir is empty - remove it
       std::string tmp_dir = Kernel_Utils::GetDirByPath( tmpFileName );
       if ( Kernel_Utils::IsEmptyDir( tmp_dir ) )
@@ -964,7 +966,7 @@ void SALOME_ContainerManager::RmTmpFile(std::string& tmpFileName)
 #else
           command = "rmdir " + tmp_dir;
 #endif
-          system(command.c_str());
+          SystemThreadSafe(command.c_str());
         }
     }
 }
@@ -1014,7 +1016,7 @@ void SALOME_ContainerManager::AddOmninamesParams(std::ostringstream& oss) const
  */ 
 //=============================================================================
 
-std::string SALOME_ContainerManager::BuildTemporaryFileName() const
+std::string SALOME_ContainerManager::BuildTemporaryFileName()
 {
   //build more complex file name to support multiple salome session
   std::string aFileName = Kernel_Utils::GetTmpFileName();
@@ -1036,17 +1038,14 @@ std::string SALOME_ContainerManager::BuildTemporaryFileName() const
  */ 
 //=============================================================================
 
-std::string
-SALOME_ContainerManager::BuildTempFileToLaunchRemoteContainer
-(const std::string& resource_name,
- const Engines::ContainerParameters& params) throw(SALOME_Exception)
+std::string SALOME_ContainerManager::BuildTempFileToLaunchRemoteContainer (const std::string& resource_name, const Engines::ContainerParameters& params, std::string& tmpFileName) const throw(SALOME_Exception)
 {
   int status;
 
-  _TmpFileName = BuildTemporaryFileName();
+  tmpFileName = BuildTemporaryFileName();
   std::ofstream tempOutputFile;
-  tempOutputFile.open(_TmpFileName.c_str(), std::ofstream::out );
-  const ParserResourcesType& resInfo = _ResManager->GetImpl()->GetResourcesDescr(resource_name);
+  tempOutputFile.open(tmpFileName.c_str(), std::ofstream::out );
+  const ParserResourcesType resInfo(_ResManager->GetImpl()->GetResourcesDescr(resource_name));
   tempOutputFile << "#! /bin/sh" << std::endl;
 
   // --- set env vars
@@ -1072,18 +1071,18 @@ SALOME_ContainerManager::BuildTempFileToLaunchRemoteContainer
 #ifdef WITHLAM
       tempOutputFile << "-x PATH,LD_LIBRARY_PATH,OMNIORB_CONFIG,SALOME_trace ";
 #elif defined(WITHOPENMPI)
-      if( getenv("OMPI_URI_FILE") == NULL )
+      if( GetenvThreadSafe("OMPI_URI_FILE") == NULL )
         tempOutputFile << "-x PATH -x LD_LIBRARY_PATH -x OMNIORB_CONFIG -x SALOME_trace";
       else{
         tempOutputFile << "-x PATH -x LD_LIBRARY_PATH -x OMNIORB_CONFIG -x SALOME_trace -ompi-server file:";
-        tempOutputFile << getenv("OMPI_URI_FILE");
+        tempOutputFile << GetenvThreadSafe("OMPI_URI_FILE");
       }
 #elif defined(WITHMPICH)
       tempOutputFile << "-nameserver " + Kernel_Utils::GetHostname();
 #endif
     }
 
-  tempOutputFile << getenv("KERNEL_ROOT_DIR") << "/bin/salome/";
+  tempOutputFile << GetenvThreadSafe("KERNEL_ROOT_DIR") << "/bin/salome/";
 
   if (params.isMPI)
     {
@@ -1107,7 +1106,7 @@ SALOME_ContainerManager::BuildTempFileToLaunchRemoteContainer
   tempOutputFile.flush();
   tempOutputFile.close();
 #ifndef WIN32
-  chmod(_TmpFileName.c_str(), 0x1ED);
+  chmod(tmpFileName.c_str(), 0x1ED);
 #endif
 
   // --- Build command
@@ -1118,36 +1117,36 @@ SALOME_ContainerManager::BuildTempFileToLaunchRemoteContainer
     {
       command = "rsh ";
       std::string commandRcp = "rcp ";
-      commandRcp += _TmpFileName;
+      commandRcp += tmpFileName;
       commandRcp += " ";
       commandRcp += resInfo.HostName;
       commandRcp += ":";
-      commandRcp += _TmpFileName;
-      status = system(commandRcp.c_str());
+      commandRcp += tmpFileName;
+      status = SystemThreadSafe(commandRcp.c_str());
     }
 
   else if (resInfo.Protocol == ssh)
     {
       command = "ssh ";
       std::string commandRcp = "scp ";
-      commandRcp += _TmpFileName;
+      commandRcp += tmpFileName;
       commandRcp += " ";
       commandRcp += resInfo.HostName;
       commandRcp += ":";
-      commandRcp += _TmpFileName;
-      status = system(commandRcp.c_str());
+      commandRcp += tmpFileName;
+      status = SystemThreadSafe(commandRcp.c_str());
     }
 
   else if (resInfo.Protocol == srun)
     {
       command = "srun -n 1 -N 1 --share --nodelist=";
       std::string commandRcp = "rcp ";
-      commandRcp += _TmpFileName;
+      commandRcp += tmpFileName;
       commandRcp += " ";
       commandRcp += resInfo.HostName;
       commandRcp += ":";
-      commandRcp += _TmpFileName;
-      status = system(commandRcp.c_str());
+      commandRcp += tmpFileName;
+      status = SystemThreadSafe(commandRcp.c_str());
     }
   else
     throw SALOME_Exception("Unknown protocol");
@@ -1156,9 +1155,8 @@ SALOME_ContainerManager::BuildTempFileToLaunchRemoteContainer
     throw SALOME_Exception("Error of connection on remote host");    
 
   command += resInfo.HostName;
-  _CommandForRemAccess = command;
   command += " ";
-  command += _TmpFileName;
+  command += tmpFileName;
 
   SCRUTE(command);
 
@@ -1166,18 +1164,18 @@ SALOME_ContainerManager::BuildTempFileToLaunchRemoteContainer
 
 }
 
-std::string SALOME_ContainerManager::GetMPIZeroNode(const std::string machine, const std::string machinesFile)
+std::string SALOME_ContainerManager::GetMPIZeroNode(const std::string machine, const std::string machinesFile) const
 {
   int status;
   std::string zeronode;
   std::string command;
   std::string tmpFile = BuildTemporaryFileName();
 
-  if( getenv("LIBBATCH_NODEFILE") == NULL )
+  if( GetenvThreadSafe("LIBBATCH_NODEFILE") == NULL )
     {
       if (_isAppliSalomeDefined)
         {
-          const ParserResourcesType& resInfo = _ResManager->GetImpl()->GetResourcesDescr(machine);
+          const ParserResourcesType resInfo(_ResManager->GetImpl()->GetResourcesDescr(machine));
 
           if (resInfo.Protocol == rsh)
             command = "rsh ";
@@ -1202,18 +1200,18 @@ std::string SALOME_ContainerManager::GetMPIZeroNode(const std::string machine, c
             command += resInfo.AppliPath; // path relative to user@machine $HOME
           else
             {
-              ASSERT(getenv("APPLI"));
-              command += getenv("APPLI"); // path relative to user@machine $HOME
+              ASSERT(GetenvThreadSafe("APPLI"));
+              command += GetenvThreadSafe("APPLI"); // path relative to user@machine $HOME
             }
 
           command += "/runRemote.sh ";
 
-          ASSERT(getenv("NSHOST")); 
-          command += getenv("NSHOST"); // hostname of CORBA name server
+          ASSERT(GetenvThreadSafe("NSHOST"));
+          command += GetenvThreadSafe("NSHOST"); // hostname of CORBA name server
 
           command += " ";
-          ASSERT(getenv("NSPORT"));
-          command += getenv("NSPORT"); // port of CORBA name server
+          ASSERT(GetenvThreadSafe("NSPORT"));
+          command += GetenvThreadSafe("NSPORT"); // port of CORBA name server
 
           command += " mpirun -np 1 hostname -s > " + tmpFile;
         }
@@ -1223,7 +1221,7 @@ std::string SALOME_ContainerManager::GetMPIZeroNode(const std::string machine, c
   else
     command = "mpirun -np 1 -machinefile " + machinesFile + " hostname -s > " + tmpFile;
 
-  status = system(command.c_str());
+  status = SystemThreadSafe(command.c_str());
   if( status == 0 ){
     std::ifstream fp(tmpFile.c_str(),std::ios::in);
     while(fp >> zeronode);
@@ -1237,7 +1235,7 @@ std::string SALOME_ContainerManager::GetMPIZeroNode(const std::string machine, c
 std::string SALOME_ContainerManager::machinesFile(const int nbproc)
 {
   std::string tmp;
-  std::string nodesFile = getenv("LIBBATCH_NODEFILE");
+  std::string nodesFile = GetenvThreadSafe("LIBBATCH_NODEFILE");
   std::string machinesFile = Kernel_Utils::GetTmpFileName();
   std::ifstream fpi(nodesFile.c_str(),std::ios::in);
   std::ofstream fpo(machinesFile.c_str(),std::ios::out);
@@ -1270,7 +1268,7 @@ std::set<pid_t> SALOME_ContainerManager::getpidofprogram(const std::string progr
   std::string cmd;
   std::string thepid;
   cmd = "pidof " + program + " > " + tmpFile;
-  system(cmd.c_str());
+  SystemThreadSafe(cmd.c_str());
   std::ifstream fpi(tmpFile.c_str(),std::ios::in);
   while(fpi >> thepid){
     thepids.insert(atoi(thepid.c_str()));
@@ -1366,6 +1364,19 @@ SALOME_ContainerManager::checkPaCOParameters(Engines::ContainerParameters & para
 
   return result;
 }
+
+char *SALOME_ContainerManager::GetenvThreadSafe(const char *name)
+{// getenv is not thread safe. See man 7 pthread.
+  Utils_Locker lock (&_getenvMutex);
+  return getenv(name);
+}
+
+int SALOME_ContainerManager::SystemThreadSafe(const char *command)
+{
+  Utils_Locker lock (&_systemMutex);
+  return system(command);
+}
+
 #ifdef WITH_PACO_PARALLEL
 
 //=============================================================================
@@ -1574,7 +1585,7 @@ SALOME_ContainerManager::BuildCommandToLaunchPaCOProxyContainer(const Engines::C
   
   // Log environnement
   std::string log_type("");
-  char * get_val = getenv("PARALLEL_LOG");
+  char * get_val = GetenvThreadSafe("PARALLEL_LOG");
   if (get_val)
     log_type = get_val;
 
@@ -1591,8 +1602,8 @@ SALOME_ContainerManager::BuildCommandToLaunchPaCOProxyContainer(const Engines::C
   // a SALOME application
   if (remote_execution)
   {
-    ASSERT(getenv("NSHOST")); 
-    ASSERT(getenv("NSPORT"));
+    ASSERT(GetenvThreadSafe("NSHOST"));
+    ASSERT(GetenvThreadSafe("NSPORT"));
 
     command << resource_definition->protocol.in();
     command << " -l ";
@@ -1600,8 +1611,8 @@ SALOME_ContainerManager::BuildCommandToLaunchPaCOProxyContainer(const Engines::C
     command << " " << hostname;
     command << " " << resource_definition->applipath.in();
     command << "/runRemote.sh ";
-    command << getenv("NSHOST") << " "; // hostname of CORBA name server
-    command << getenv("NSPORT") << " "; // port of CORBA name server
+    command << GetenvThreadSafe("NSHOST") << " "; // hostname of CORBA name server
+    command << GetenvThreadSafe("NSPORT") << " "; // port of CORBA name server
   }
 
   command << exe_name;
@@ -1640,7 +1651,7 @@ SALOME_ContainerManager::BuildCommandToLaunchPaCONodeContainer(const Engines::Co
   
   // Log environnement
   std::string log_type("");
-  char * get_val = getenv("PARALLEL_LOG");
+  char * get_val = GetenvThreadSafe("PARALLEL_LOG");
   if (get_val)
     log_type = get_val;
 
@@ -1679,8 +1690,8 @@ SALOME_ContainerManager::BuildCommandToLaunchPaCONodeContainer(const Engines::Co
       // a SALOME application
       if (remote_execution)
       {
-        ASSERT(getenv("NSHOST")); 
-        ASSERT(getenv("NSPORT"));
+        ASSERT(GetenvThreadSafe("NSHOST"));
+        ASSERT(GetenvThreadSafe("NSPORT"));
 
         command_node_stream << resource_definition->protocol.in();
         command_node_stream << " -l ";
@@ -1688,8 +1699,8 @@ SALOME_ContainerManager::BuildCommandToLaunchPaCONodeContainer(const Engines::Co
         command_node_stream << " " << hostname;
         command_node_stream << " " << resource_definition->applipath.in();
         command_node_stream << "/runRemote.sh ";
-        command_node_stream << getenv("NSHOST") << " "; // hostname of CORBA name server
-        command_node_stream << getenv("NSPORT") << " "; // port of CORBA name server
+        command_node_stream << GetenvThreadSafe("NSHOST") << " "; // hostname of CORBA name server
+        command_node_stream << GetenvThreadSafe("NSPORT") << " "; // port of CORBA name server
       }
 
       command_node_stream << exe_name;
@@ -1737,7 +1748,7 @@ SALOME_ContainerManager::BuildCommandToLaunchPaCONodeContainer(const Engines::Co
     command_remote_stream << hostname << ":" << resource_definition->applipath.in();
     command_remote_stream <<  "/" << machine_file_name.substr(last+1);
 
-    int status = system(command_remote_stream.str().c_str());
+    int status = SystemThreadSafe(command_remote_stream.str().c_str());
     if (status == -1)
     {
       INFOS("copy of the MPI machine file failed ! - sorry !");
@@ -1756,8 +1767,8 @@ SALOME_ContainerManager::BuildCommandToLaunchPaCONodeContainer(const Engines::Co
     // a SALOME application
     if (remote_execution)
     {
-      ASSERT(getenv("NSHOST")); 
-      ASSERT(getenv("NSPORT"));
+      ASSERT(GetenvThreadSafe("NSHOST"));
+      ASSERT(GetenvThreadSafe("NSPORT"));
 
       command_nodes << resource_definition->protocol.in();
       command_nodes << " -l ";
@@ -1765,8 +1776,8 @@ SALOME_ContainerManager::BuildCommandToLaunchPaCONodeContainer(const Engines::Co
       command_nodes << " " << hostname;
       command_nodes << " " << resource_definition->applipath.in();
       command_nodes << "/runRemote.sh ";
-      command_nodes << getenv("NSHOST") << " "; // hostname of CORBA name server
-      command_nodes << getenv("NSPORT") << " "; // port of CORBA name server
+      command_nodes << GetenvThreadSafe("NSHOST") << " "; // hostname of CORBA name server
+      command_nodes << GetenvThreadSafe("NSPORT") << " "; // port of CORBA name server
     }
 
     if (std::string(resource_definition->mpiImpl.in()) == "lam")
@@ -1817,7 +1828,7 @@ SALOME_ContainerManager::LogConfiguration(const std::string & log_type,
   {
     // default into a file...
     std::string logFilename = "/tmp/" + container_name + "_" + hostname + "_" + exe_type + "_";
-    logFilename += std::string(getenv("USER")) + ".log";
+    logFilename += std::string(GetenvThreadSafe("USER")) + ".log";
     end = " > " + logFilename + " 2>&1 & ";
   }
 }
@@ -1830,7 +1841,7 @@ SALOME_ContainerManager::LaunchPaCOProxyContainer(const std::string& command,
   PaCO::InterfaceManager_ptr container_proxy = PaCO::InterfaceManager::_nil();
 
   MESSAGE("[LaunchPaCOProxyContainer] Launch command");
-  int status = system(command.c_str());
+  int status = SystemThreadSafe(command.c_str());
   if (status == -1) {
     INFOS("[LaunchPaCOProxyContainer] failed : system command status -1");
     return container_proxy;
@@ -1901,7 +1912,7 @@ SALOME_ContainerManager::LaunchPaCONodeContainer(const std::string& command,
                                                  SALOME_ContainerManager::actual_launch_machine_t & vect_machine)
 {
   INFOS("[LaunchPaCONodeContainer] Launch command");
-  int status = system(command.c_str());
+  int status = SystemThreadSafe(command.c_str());
   if (status == -1) {
     INFOS("[LaunchPaCONodeContainer] failed : system command status -1");
     return false;
index 1f64f7b65f6aaf9235de1aabe245e105cf98800a..3aa4b4a7e04c237e5c2fa8f4b55833b1ede9ec2c 100644 (file)
 #include "SALOME_ResourcesManager.hxx"
 #include "SALOME_LoadRateManager.hxx"
 
+#include "Utils_Mutex.hxx"
+
 #include <string>
 #include <set>
 
 class SALOME_NamingService;
 
-class CONTAINER_EXPORT SALOME_ContainerManager:
-  public POA_Engines::ContainerManager
+class CONTAINER_EXPORT SALOME_ContainerManager : public POA_Engines::ContainerManager
 {
 
 public:
@@ -45,8 +46,7 @@ public:
   ~SALOME_ContainerManager();
 
   // Corba Methods
-  Engines::Container_ptr
-  GiveContainer(const Engines::ContainerParameters& params);
+  Engines::Container_ptr GiveContainer(const Engines::ContainerParameters& params);
 
   void ShutdownContainers();
 
@@ -67,16 +67,17 @@ protected:
 
   std::string BuildCommandToLaunchRemoteContainer(const std::string & resource_name,
                                                   const Engines::ContainerParameters& params, 
-                                                  const std::string& container_exe="SALOME_Container");
+                                                  const std::string& container_exe="SALOME_Container") const;
 
   std::string BuildCommandToLaunchLocalContainer(const Engines::ContainerParameters& params,
                                                  const std::string& machinesFile,
-                                                 const std::string& container_exe="SALOME_Container");
+                                                 const std::string& container_exe,//"SALOME_Container"
+                                                 std::string& tmpFileName) const;
 
   std::string BuildTempFileToLaunchRemoteContainer(const std::string& resource_name,
-                                                   const Engines::ContainerParameters& params) throw(SALOME_Exception);
+                                                   const Engines::ContainerParameters& params, std::string& tmpFileName) const throw(SALOME_Exception);
 
-  void RmTmpFile(std::string& tmpFile);
+  static void RmTmpFile(std::string& tmpFile);
 
   void AddOmninamesParams(std::string& command) const;
 
@@ -84,17 +85,15 @@ protected:
 
   void AddOmninamesParams(std::ofstream& fileStream) const;
 
-  std::string BuildTemporaryFileName() const;
+  static std::string BuildTemporaryFileName();
 
-  std::string GetMPIZeroNode(const std::string machine, const std::string machinesFile);
+  std::string GetMPIZeroNode(const std::string machine, const std::string machinesFile) const;
 
   std::string machinesFile(const int nbproc);
 
   std::set<pid_t> getpidofprogram(const std::string program);
 
-  std::string getCommandToRunRemoteProcess(AccessProtocolType protocol,
-                                           const std::string & hostname,
-                                           const std::string & username);
+ static std::string getCommandToRunRemoteProcess(AccessProtocolType protocol, const std::string & hostname, const std::string & username);
 
   Engines::Container_ptr
   LaunchContainer(const Engines::ContainerParameters& params,
@@ -109,13 +108,6 @@ protected:
   SALOME_ResourcesManager *_ResManager;
   SALOME_NamingService *_NS;
 
-  //! attribute that contains current tmp files generated
-  std::string _TmpFileName;
-
-  //! contains the rsh or ssh command to access directly to machine.
-  //  Only used by this->RmTmpFile in case of a remote launch.
-  std::string _CommandForRemAccess;
-
   //! different behaviour if $APPLI exists (SALOME Application) 
   bool _isAppliSalomeDefined;
 
@@ -124,6 +116,9 @@ protected:
 
   static omni_mutex _numInstanceMutex ; // lib and instance protection
 
+  //! attributes to allow concurrency for // GiveContainer
+  Utils_Mutex _giveContainerMutex1;
+
   pid_t _pid_mpiServer;
 
   // Begin of PacO++ Parallel extension
@@ -163,5 +158,11 @@ protected:
                           const std::string& name,
                           SALOME_ContainerManager::actual_launch_machine_t & vect_machine);
   // End of PaCO++ Parallel extension
+public:
+  static char *GetenvThreadSafe(const char *name);
+  static int SystemThreadSafe(const char *command);
+private:
+  static Utils_Mutex _getenvMutex;
+  static Utils_Mutex _systemMutex;
 };
 #endif
index 9cbc8a615f1f17f8ddceacc0786c790d1a341cd5..07f1f7baed934b01e21cd9244b86069575d91251 100644 (file)
@@ -106,6 +106,13 @@ class PyScriptNode_i (Engines__POA.PyScriptNode,Generic):
     except:
       raise SALOME.SALOME_Exception(SALOME.ExceptionStruct(SALOME.BAD_PARAM,"","PyScriptNode (%s) : code to be executed \"%s\"" %(self.nodeName,code),0))
 
+  def assignNewCompiledCode(self,codeStr):
+    try:
+      self.code=codeStr
+      self.ccode=compile(codeStr,self.nodeName,'exec')
+    except:
+      raise SALOME.SALOME_Exception(SALOME.ExceptionStruct(SALOME.BAD_PARAM,"","PyScriptNode.assignNewCompiledCode (%s) : code to be executed \"%s\"" %(self.nodeName,codeStr),0))
+
   def execute(self,outargsname,argsin):
     """Execute the script stored in attribute ccode with pickled args (argsin)"""
     try:
index 638fee21eada1792d5ae1b6c3aa13751a4acc6d9..42c754bb2c1e62452daa2c095fcdc1e96b6f5aa6 100644 (file)
@@ -576,9 +576,9 @@ SALOME_NamingService::ResolveComponent(const char* hostname,
 
 std::string SALOME_NamingService::ContainerName(const char *containerName)
 {
-  std::string ret;
+  std::string ret,containerNameCpp(containerName);
 
-  if (strlen(containerName) == 0)
+  if (containerNameCpp.empty())
     ret = "FactoryServer";
   else
     ret = containerName;
@@ -599,8 +599,7 @@ std::string SALOME_NamingService::ContainerName(const char *containerName)
  */
 // ============================================================================
 
-std::string 
-SALOME_NamingService::ContainerName(const Engines::ContainerParameters& params)
+std::string SALOME_NamingService::ContainerName(const Engines::ContainerParameters& params)
 {
   int nbproc;
 
@@ -611,13 +610,13 @@ SALOME_NamingService::ContainerName(const Engines::ContainerParameters& params)
   else
     nbproc = params.nb_proc;
 
-  std::string ret = ContainerName(params.container_name);
+  std::string ret(ContainerName(params.container_name));
 
   if ( nbproc >= 1 )
     {
-      char *suffix = new char[8];
-      sprintf(suffix, "_%d", nbproc);
-      ret += suffix;
+         std::ostringstream suffix;
+         suffix << "_" << nbproc;
+      ret += suffix.str();
     }
 
   return ret;
@@ -637,10 +636,9 @@ SALOME_NamingService::ContainerName(const Engines::ContainerParameters& params)
  */
 // ============================================================================
 
-std::string SALOME_NamingService::BuildContainerNameForNS(const char *containerName,
-                                                     const char *hostname)
+std::string SALOME_NamingService::BuildContainerNameForNS(const char *containerName, const char *hostname)
 {
-  std::string ret = "/Containers/";
+  std::string ret("/Containers/");
   ret += hostname;
   ret += "/";
   ret += ContainerName(containerName);
@@ -660,12 +658,9 @@ std::string SALOME_NamingService::BuildContainerNameForNS(const char *containerN
  */
 // ============================================================================
 
-std::string
-SALOME_NamingService::
-BuildContainerNameForNS(const Engines::ContainerParameters& params,
-                        const char *hostname)
+std::string SALOME_NamingService::BuildContainerNameForNS(const Engines::ContainerParameters& params, const char *hostname)
 {
-  std::string ret = "/Containers/";
+  std::string ret("/Containers/");
   ret += hostname;
   ret += "/";
   ret += ContainerName(params);
@@ -732,8 +727,7 @@ throw(ServiceUnreachable)
  */ 
 // ============================================================================
 
-bool SALOME_NamingService::Create_Directory(const char* Path)
-throw(ServiceUnreachable)
+bool SALOME_NamingService::Create_Directory(const char* Path) throw(ServiceUnreachable)
 {
   MESSAGE("BEGIN OF Create_Directory");
 
@@ -777,8 +771,7 @@ throw(ServiceUnreachable)
  */ 
 // ============================================================================
 
-bool SALOME_NamingService::Change_Directory(const char* Path)
-throw(ServiceUnreachable)
+bool SALOME_NamingService::Change_Directory(const char* Path) throw(ServiceUnreachable)
 {
 //   MESSAGE("BEGIN OF Change_Directory " << Path);
   Utils_Locker lock (&_myMutex);
@@ -878,8 +871,7 @@ throw(ServiceUnreachable)
  */ 
 // ============================================================================
 
-char* SALOME_NamingService::Current_Directory()
-throw(ServiceUnreachable)
+char *SALOME_NamingService::Current_Directory() throw(ServiceUnreachable)
 {
   MESSAGE("BEGIN OF Current_Directory");
 
@@ -931,8 +923,7 @@ throw(ServiceUnreachable)
  */ 
 // ============================================================================
 
-void SALOME_NamingService::list()
-throw(ServiceUnreachable)
+void SALOME_NamingService::list() throw(ServiceUnreachable)
 {
   MESSAGE("Begin of list");
 
@@ -996,10 +987,10 @@ throw(ServiceUnreachable)
  */ 
 // ============================================================================
 
-std::vector<std::string> SALOME_NamingService::list_directory()
-throw(ServiceUnreachable)
+std::vector<std::string> SALOME_NamingService::list_directory() throw(ServiceUnreachable)
 {
 //   MESSAGE("list_directory");
+  Utils_Locker lock (&_myMutex);
   std::vector<std::string> dirList ;
   dirList.resize(0);
 
@@ -1050,10 +1041,10 @@ throw(ServiceUnreachable)
  */ 
 // ============================================================================
 
-std::vector<std::string> SALOME_NamingService::list_subdirs()
-throw(ServiceUnreachable)
+std::vector<std::string> SALOME_NamingService::list_subdirs() throw(ServiceUnreachable)
 {
   MESSAGE("list_subdirs");
+  Utils_Locker lock (&_myMutex);
   std::vector<std::string> dirList ;
   dirList.resize(0);
 
@@ -1283,8 +1274,7 @@ throw(ServiceUnreachable)
  */ 
 // ============================================================================
 
-void SALOME_NamingService::Destroy_Directory(const char* Path)
-throw(ServiceUnreachable)
+void SALOME_NamingService::Destroy_Directory(const char* Path) throw(ServiceUnreachable)
 {
   MESSAGE("BEGIN OF Destroy_Directory " << Path);
 
@@ -1458,10 +1448,10 @@ throw(ServiceUnreachable)
  */ 
 // ============================================================================
 
-void SALOME_NamingService::Destroy_FullDirectory(const char* Path)
-throw(ServiceUnreachable)
+void SALOME_NamingService::Destroy_FullDirectory(const char* Path) throw(ServiceUnreachable)
 {
   MESSAGE("begin of Destroy_FullDirectory " << Path);
+  //no need to lock here because method calls are threadsafe.
   if( Change_Directory(Path) )
     {
       std::vector<std::string> contList = list_directory();
@@ -1484,7 +1474,7 @@ throw(ServiceUnreachable)
 void SALOME_NamingService::_initialize_root_context()
 {
   //MESSAGE("Get the root context");
-
+  //no lock here because initialization is expected to be done once.
   try
     {
       CORBA::Object_var obj = _orb->resolve_initial_references("NameService");
index bde37e61755d2d59a5eeccc04553b8d7b4edf0cb..d6a53c28e2e6c138bd5421d827ec1292e03192df 100644 (file)
@@ -54,49 +54,30 @@ public:
   virtual ~SALOME_NamingService();
 
   void init_orb(CORBA::ORB_ptr orb=0);
-  void Register(CORBA::Object_ptr ObjRef,
-                const char* Path) 
-    throw(ServiceUnreachable);
-  CORBA::Object_ptr Resolve(const char* Path)
-    throw( ServiceUnreachable); 
-  CORBA::Object_ptr ResolveFirst(const char* Path)
-    throw( ServiceUnreachable); 
+  void Register(CORBA::Object_ptr ObjRef, const char* Path) throw(ServiceUnreachable);
+  CORBA::Object_ptr Resolve(const char* Path) throw( ServiceUnreachable); 
+  CORBA::Object_ptr ResolveFirst(const char* Path) throw( ServiceUnreachable); 
   CORBA::Object_ptr ResolveComponent(const char* hostname,
                                      const char* containerName,
                                      const char* componentName,
-                                     const int nbproc=0)
-    throw(ServiceUnreachable);
+                                     const int nbproc=0) throw(ServiceUnreachable);
   std::string ContainerName(const char *ContainerName);
   std::string ContainerName(const Engines::ContainerParameters& params);
-  std::string BuildContainerNameForNS(const char *ContainerName,
-                                      const char *hostname);
-  std::string 
-  BuildContainerNameForNS(const Engines::ContainerParameters& params,
-                          const char *hostname);
+  std::string BuildContainerNameForNS(const char *ContainerName, const char *hostname);
+  std::string BuildContainerNameForNS(const Engines::ContainerParameters& params, const char *hostname);
 
-  int Find(const char* name)
-    throw(ServiceUnreachable);
-  bool Create_Directory(const char* Path)
-    throw(ServiceUnreachable);
-  bool Change_Directory(const char* Path)
-    throw(ServiceUnreachable);
-  char* Current_Directory()
-    throw(ServiceUnreachable);
-  void list()
-    throw(ServiceUnreachable);
-  std::vector<std::string> list_directory()
-    throw(ServiceUnreachable);
-  std::vector<std::string> list_subdirs()
-    throw(ServiceUnreachable);
-  std::vector<std::string> list_directory_recurs()
-    throw(ServiceUnreachable);
-  void Destroy_Name(const char* Path)
-    throw(ServiceUnreachable);
-  virtual void Destroy_Directory(const char* Path)
-    throw(ServiceUnreachable);
-  virtual void Destroy_FullDirectory(const char* Path)
-    throw(ServiceUnreachable);
-  char* getIORaddr();
+  int Find(const char* name) throw(ServiceUnreachable);
+  bool Create_Directory(const char* Path) throw(ServiceUnreachable);
+  bool Change_Directory(const char* Path) throw(ServiceUnreachable);
+  char* Current_Directory() throw(ServiceUnreachable);
+  void list() throw(ServiceUnreachable);
+  std::vector<std::string> list_directory() throw(ServiceUnreachable);
+  std::vector<std::string> list_subdirs() throw(ServiceUnreachable);
+  std::vector<std::string> list_directory_recurs() throw(ServiceUnreachable);
+  void Destroy_Name(const char* Path) throw(ServiceUnreachable);
+  virtual void Destroy_Directory(const char* Path) throw(ServiceUnreachable);
+  virtual void Destroy_FullDirectory(const char* Path) throw(ServiceUnreachable);
+  char *getIORaddr();
   CORBA::ORB_ptr orb();
 
 protected:
index 1aed4d065e5a13450778ee5de2039cfc9794bb48..786f57599b4b5493c7f5a5c12bfb29a758410dd2 100644 (file)
@@ -500,11 +500,16 @@ const MapOfParserResourcesType& ResourcesManager_cpp::GetList() const
   return _resourcesList;
 }
 
-std::string ResourcesManager_cpp::Find(const std::string& policy, const std::vector<std::string>& listOfResources)
+//! threadsafe
+std::string ResourcesManager_cpp::Find(const std::string& policy, const std::vector<std::string>& listOfResources) const
 {
-  if(_resourceManagerMap.count(policy)==0)
-    return _resourceManagerMap[""]->Find(listOfResources, _resourcesList);
-  return _resourceManagerMap[policy]->Find(listOfResources, _resourcesList);
+  std::map<std::string , LoadRateManager*>::const_iterator it(_resourceManagerMap.find(policy));
+  if(it==_resourceManagerMap.end())
+       {
+         it=_resourceManagerMap.find("");
+         return ((*it).second)->Find(listOfResources, _resourcesList);
+       }
+  return ((*it).second)->Find(listOfResources, _resourcesList);
 }
 
 //=============================================================================
@@ -570,12 +575,12 @@ ResourcesManager_cpp::KeepOnlyResourcesWithComponent(std::vector<std::string>& r
   resources=kept_resources;
 }
 
-
-ParserResourcesType 
-ResourcesManager_cpp::GetResourcesDescr(const std::string & name)
+//! thread safe
+ParserResourcesType ResourcesManager_cpp::GetResourcesDescr(const std::string & name) const
 {
-  if (_resourcesList.find(name) != _resourcesList.end())
-    return _resourcesList[name];
+  MapOfParserResourcesType::const_iterator it(_resourcesList.find(name));
+  if (it != _resourcesList.end())
+    return (*it).second;
   else
   {
     std::string error("[GetResourcesDescr] Resource does not exist: ");
index eaa6eaa8c04f375845bbc901773ff6653eef9659..1ab18a23e14daa331d7421b3b38310c0ff899d17 100644 (file)
@@ -87,8 +87,7 @@ class RESOURCESMANAGER_EXPORT ResourcesManager_cpp
     std::vector<std::string> 
     GetFittingResources(const resourceParams& params) throw(ResourcesException);
 
-    std::string Find(const std::string& policy, 
-                     const std::vector<std::string>& listOfResources);
+    std::string Find(const std::string& policy, const std::vector<std::string>& listOfResources) const;
 
     void AddResourceInCatalog (const ParserResourcesType & new_resource);
 
@@ -100,7 +99,8 @@ class RESOURCESMANAGER_EXPORT ResourcesManager_cpp
 
     const MapOfParserResourcesType& GetList() const;
 
-    ParserResourcesType GetResourcesDescr(const std::string & name);
+    //! thread safe
+    ParserResourcesType GetResourcesDescr(const std::string & name) const;
 
   protected:
     
index 60eacc2c0f613f7d136e5b806ec6e846d85f69af..f251cb3f0c16ff5a32b73055e53728055d84c252 100644 (file)
@@ -25,7 +25,7 @@
 #include <map>
 
 std::string LoadRateManagerFirst::Find(const std::vector<std::string>& hosts,
-                                  MapOfParserResourcesType& resList)
+                                       const MapOfParserResourcesType& resList)
 {
   if (hosts.size() == 0)
     return std::string("");
@@ -34,7 +34,7 @@ std::string LoadRateManagerFirst::Find(const std::vector<std::string>& hosts,
 }
 
 std::string LoadRateManagerCycl::Find(const std::vector<std::string>& hosts,
-                                 MapOfParserResourcesType& resList)
+                                      const MapOfParserResourcesType& resList)
 {
   static int imachine = 0;
   static int iproc = 0;
@@ -43,7 +43,10 @@ std::string LoadRateManagerCycl::Find(const std::vector<std::string>& hosts,
   if (hosts.size() == 0)
     return std::string("");
   else{
-    ParserResourcesType resource = resList[std::string(hosts[imachine])];
+    MapOfParserResourcesType::const_iterator it(resList.find(hosts[imachine]));
+    ParserResourcesType resource;
+    if(it!=resList.end())
+      resource = (*it).second;
     int nbproc = resource.DataForSort._nbOfProcPerNode * resource.DataForSort._nbOfNodes;
     if( nbproc <= 0) nbproc = 1;
     if( iproc < nbproc ){
@@ -61,7 +64,7 @@ std::string LoadRateManagerCycl::Find(const std::vector<std::string>& hosts,
 }
 
 std::string LoadRateManagerAltCycl::Find(const std::vector<std::string>& hosts,
-                                    MapOfParserResourcesType& resList)
+                                         const MapOfParserResourcesType& resList)
 {
   if (hosts.size() == 0)
     return std::string("");
index 462a6011ab47b43ac9c2e0ac7d5df3d23c2ac196..95b8cb92a46f9a721c76366daadfb1a92bdbec63 100644 (file)
@@ -32,28 +32,28 @@ class RESOURCESMANAGER_EXPORT LoadRateManager
 {
   public:
     virtual std::string Find(const std::vector<std::string>& hosts,
-                             MapOfParserResourcesType& resList){return "";};
+                             const MapOfParserResourcesType& resList) { return ""; }
 };
 
-class RESOURCESMANAGER_EXPORT LoadRateManagerFirst:public LoadRateManager
+class RESOURCESMANAGER_EXPORT LoadRateManagerFirst : public LoadRateManager
 {
   public:
     virtual std::string Find(const std::vector<std::string>& hosts,
-                             MapOfParserResourcesType& resList);
+                             const MapOfParserResourcesType& resList);
 };
 
-class RESOURCESMANAGER_EXPORT LoadRateManagerCycl :public LoadRateManager
+class RESOURCESMANAGER_EXPORT LoadRateManagerCycl : public LoadRateManager
 {
   public:
     virtual std::string Find(const std::vector<std::string>& hosts,
-                             MapOfParserResourcesType& resList);
+                             const MapOfParserResourcesType& resList);
 };
 
-class RESOURCESMANAGER_EXPORT LoadRateManagerAltCycl :public LoadRateManager
+class RESOURCESMANAGER_EXPORT LoadRateManagerAltCycl : public LoadRateManager
 {
   public:
     virtual std::string Find(const std::vector<std::string>& hosts,
-                             MapOfParserResourcesType& resList);
+                             const MapOfParserResourcesType& resList);
   protected:
     std::map<std::string,int> _numberOfUses;
 };
index 42f38c4d62c7c2f637125fd321823fd85764aed7..17b6d2b68c33f12c2e331e462172af22322f09b5 100644 (file)
@@ -56,16 +56,20 @@ const char *SALOME_ResourcesManager::_ResourcesManagerNameInNS = "/ResourcesMana
  */ 
 //=============================================================================
 
-SALOME_ResourcesManager::
-SALOME_ResourcesManager(CORBA::ORB_ptr orb, 
-                        PortableServer::POA_var poa, 
-                        SALOME_NamingService *ns,
-                        const char *xmlFilePath) : _rm(xmlFilePath)
+SALOME_ResourcesManager::SALOME_ResourcesManager(CORBA::ORB_ptr orb, PortableServer::POA_var poa, SALOME_NamingService *ns, const char *xmlFilePath) : _rm(xmlFilePath)
 {
   MESSAGE("SALOME_ResourcesManager constructor");
   _NS = ns;
   _orb = CORBA::ORB::_duplicate(orb) ;
-  _poa = PortableServer::POA::_duplicate(poa) ;
+  //
+  PortableServer::POAManager_var pman = poa->the_POAManager();
+  CORBA::PolicyList policies;
+  policies.length(1);
+  PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::SINGLE_THREAD_MODEL));
+  policies[0] = PortableServer::ThreadPolicy::_duplicate(threadPol);
+  _poa = poa->create_POA("SingleThreadPOA",pman,policies);
+  threadPol->destroy();
+  //
   PortableServer::ObjectId_var id = _poa->activate_object(this);
   CORBA::Object_var obj = _poa->id_to_reference(id);
   Engines::ResourcesManager_var refContMan = Engines::ResourcesManager::_narrow(obj);
@@ -91,7 +95,15 @@ SALOME_ResourcesManager::SALOME_ResourcesManager(CORBA::ORB_ptr orb,
   MESSAGE("SALOME_ResourcesManager constructor");
   _NS = ns;
   _orb = CORBA::ORB::_duplicate(orb) ;
-  _poa = PortableServer::POA::_duplicate(poa) ;
+  //
+  PortableServer::POAManager_var pman = poa->the_POAManager();
+  CORBA::PolicyList policies;
+  policies.length(1);
+  PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::SINGLE_THREAD_MODEL));
+  policies[0] = PortableServer::ThreadPolicy::_duplicate(threadPol);
+  _poa = poa->create_POA("SingleThreadPOA",pman,policies);
+  threadPol->destroy();
+  //
   PortableServer::ObjectId_var id = _poa->activate_object(this);
   CORBA::Object_var obj = _poa->id_to_reference(id);
   Engines::ResourcesManager_var refContMan = Engines::ResourcesManager::_narrow(obj);