Salome HOME
Implementation of launch of external from SALOME processes
authorAnthony Geay <anthony.geay@edf.fr>
Wed, 12 Jun 2019 05:18:20 +0000 (07:18 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Thu, 13 Jun 2019 14:13:39 +0000 (16:13 +0200)
26 files changed:
idl/CMakeLists.txt
idl/SALOME_CommonTypes.idl [new file with mode: 0644]
idl/SALOME_ExternalServerLauncher.idl [new file with mode: 0644]
idl/SALOME_SDS.idl
src/Container/CMakeLists.txt
src/Container/SALOME_CPythonHelper.cxx [new file with mode: 0644]
src/Container/SALOME_CPythonHelper.hxx [new file with mode: 0644]
src/Container/SALOME_ContainerManager.cxx
src/Container/SALOME_ContainerManager.hxx
src/KERNEL_PY/__init__.py
src/KERNEL_PY/salome_kernel.py
src/KERNEL_PY/salome_study.py
src/Launcher/CMakeLists.txt
src/Launcher/SALOME_ExternalServerHandler.cxx [new file with mode: 0644]
src/Launcher/SALOME_ExternalServerHandler.hxx [new file with mode: 0644]
src/Launcher/SALOME_ExternalServerLauncher.cxx [new file with mode: 0644]
src/Launcher/SALOME_ExternalServerLauncher.hxx [new file with mode: 0644]
src/Launcher/SALOME_LauncherException.cxx [new file with mode: 0644]
src/Launcher/SALOME_LauncherException.hxx [new file with mode: 0644]
src/Launcher/SALOME_LauncherServer.cxx
src/SALOMESDS/CMakeLists.txt
src/SALOMESDS/SALOMESDS_DataScopeServer.cxx
src/SALOMESDS/SALOMESDS_DataScopeServer.hxx
src/SALOMESDS/SALOMESDS_DataServerManager.cxx
src/SALOMESDS/SALOMESDS_DataServerManager.hxx
src/SALOMESDS/SALOME_DataScopeServer.cxx

index 280c254308f8bca592665caabbf92183e587ee95..df7d3397e3a5d42605df052d0973a7f81ffc98f2 100644 (file)
@@ -53,6 +53,8 @@ SET(SalomeIDLKernel_IDLSOURCES
   SALOME_MPIObject.idl
   SALOME_TestComponent.idl
   SALOME_TestModuleCatalog.idl
+  SALOME_CommonTypes.idl
+  SALOME_ExternalServerLauncher.idl
   ${CMAKE_CURRENT_BINARY_DIR}/Calcium_Ports.idl
 )
 
diff --git a/idl/SALOME_CommonTypes.idl b/idl/SALOME_CommonTypes.idl
new file mode 100644 (file)
index 0000000..f5e6248
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright (C) 2019  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#ifndef __SALOME_COMMONTYPES_IDL__
+#define __SALOME_COMMONTYPES_IDL__
+
+module SALOME
+{
+  typedef sequence<string> StringVec;
+  typedef sequence<long> LongVec;
+};
+
+#endif
diff --git a/idl/SALOME_ExternalServerLauncher.idl b/idl/SALOME_ExternalServerLauncher.idl
new file mode 100644 (file)
index 0000000..7344d20
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (C) 2019  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#ifndef __SALOME_EXTERNALSERVERLAUNCHER_IDL__
+#define __SALOME_EXTERNALSERVERLAUNCHER_IDL__
+
+#include "SALOME_Exception.idl"
+#include "SALOME_CommonTypes.idl"
+
+module SALOME
+{
+  typedef sequence<string> CmdList;
+
+  interface ExternalServerHandler
+  {
+    long getPID();
+    string getName();
+    void killMe();
+    void ping();
+    void shutdown();
+    LongVec listOfChildrenPID();
+  };
+  
+  interface ExternalServerLauncher
+  {
+    ExternalServerHandler launchServer( in string server_name, in CmdList command_list ) raises(SALOME::SALOME_Exception);
+    void cleanServersInNS();
+    StringVec listServersInNS();
+    ExternalServerHandler retrieveServerRefGivenNSEntry( in string ns_entry ) raises(SALOME::SALOME_Exception);
+    void registerToKill(in string server_name, in long PID) raises (SALOME::SALOME_Exception);
+    void shutdownServers() raises (SALOME::SALOME_Exception);
+    string gethostname();
+  };
+};
+
+#endif
index 09281e48f79c44b302c837df9882ef5f32314780..749b400aaa5ab21e7648e36738904095d5e009f5 100644 (file)
 
 // Author : Anthony GEAY (EDF R&D)
 
+#ifndef __SALOME_SDS_IDL__
+#define __SALOME_SDS_IDL__
+
 #include "SALOME_GenericObj.idl"
 #include "SALOME_Exception.idl"
+#include "SALOME_CommonTypes.idl"
 
 module SALOME
 {
-  typedef sequence<string> StringVec;
   typedef sequence<octet> ByteVec;
   typedef sequence<ByteVec> SeqOfByteVec;
   
@@ -178,3 +181,5 @@ module SALOME
     RequestSwitcherDSM getRequestSwitcher();
   };
 };
+
+#endif
index 6917dbde609106b209aac7b5c5935913c5415b4e..ca577cc8f07ff4ab3c33949b148498da47292cad 100644 (file)
@@ -80,6 +80,7 @@ SET(SalomeContainer_SOURCES
   Container_init_python.cxx
   SALOME_ContainerManager.cxx
   Salome_file_i.cxx
+  SALOME_CPythonHelper.cxx
 )
 
 ADD_LIBRARY(SalomeContainer ${SalomeContainer_SOURCES})
diff --git a/src/Container/SALOME_CPythonHelper.cxx b/src/Container/SALOME_CPythonHelper.cxx
new file mode 100644 (file)
index 0000000..c1032a2
--- /dev/null
@@ -0,0 +1,98 @@
+// Copyright (C) 2019  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#include "SALOME_CPythonHelper.hxx"
+
+void SALOME_CPythonHelper::initializePython(int argc, char *argv[])
+{
+  Py_Initialize();
+  PyEval_InitThreads();
+  wchar_t **changed_argv = new wchar_t*[argc]; // Setting arguments
+  for (int i = 0; i < argc; i++)
+    changed_argv[i] = Py_DecodeLocale(argv[i], NULL);
+  PySys_SetArgv(argc, changed_argv);
+  PyObject *mainmod(PyImport_AddModule("__main__"));
+  _globals=PyModule_GetDict(mainmod);
+  if(PyDict_GetItemString(_globals, "__builtins__") == NULL)
+    {
+      PyObject *bimod(PyImport_ImportModule("__builtin__"));
+      if (bimod == NULL || PyDict_SetItemString(_globals, "__builtins__", bimod) != 0)
+        Py_FatalError("can't add __builtins__ to __main__");
+      Py_XDECREF(bimod);
+    }
+  _locals=PyDict_New();
+  PyObject *tmp(PyList_New(0));
+  _pickler=PyImport_ImportModuleLevel(const_cast<char *>("pickle"),_globals,_locals,tmp,0);
+  _subprocess=PyImport_ImportModuleLevel(const_cast<char *>("subprocess"),_globals,_locals,tmp,0);
+  PyObject *socket(PyImport_ImportModuleLevel(const_cast<char *>("socket"),_globals,_locals,tmp,0));
+  PyDict_SetItemString(_globals,"sp",_subprocess);
+  PyDict_SetItemString(_globals,"socket",socket);
+}
+
+void SALOME_CPythonHelper::registerToSalomePiDict(const std::string& processName, long pid) const
+{
+  PyObject *mod(PyImport_ImportModule("addToKillList"));//new value
+  if(!mod)
+    return;
+  PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));//new value
+  if(!meth)
+    { Py_XDECREF(mod); return ; }
+  PyObject *args(PyTuple_New(2));
+  PyTuple_SetItem(args,0,PyLong_FromLong(pid));
+  PyTuple_SetItem(args,1,PyUnicode_FromString(processName.c_str()));
+  PyObject *res(PyObject_CallObject(meth,args));
+  Py_XDECREF(args);
+  Py_XDECREF(res);
+  Py_XDECREF(meth);
+  Py_XDECREF(mod);
+}
+
+std::vector<long> SALOME_CPythonHelper::evalVL(const std::string& pyCode) const
+{
+  PyObject* code(Py_CompileString(pyCode.c_str(),"evalVL.py", Py_eval_input));
+  PyObject *res(PyEval_EvalCode( code, _globals, _locals));
+  Py_DECREF(code);
+  Py_ssize_t n(PyList_Size(res));
+  std::vector<long> ret(n);
+  for(auto i = 0; i<n; ++i)
+    {
+      PyObject *elt(PyList_GetItem(res,i));//borrowed
+      ret[i]=PyLong_AsLong(elt);
+    }
+  Py_DECREF(res);
+  return ret;
+}
+
+std::string SALOME_CPythonHelper::evalS(const std::string& pyCode) const
+{
+  PyObject* code(Py_CompileString(pyCode.c_str(),"evalS.py", Py_eval_input));
+  PyObject *res(PyEval_EvalCode( code, _globals, _locals));
+  Py_DECREF(code);
+  std::string ret(PyUnicode_AsUTF8(res));
+  Py_DECREF(res);
+  return ret;
+}
+
+SALOME_CPythonHelper::~SALOME_CPythonHelper()
+{
+  // _globals is borrowed ref -> do nothing
+  Py_XDECREF(_locals);
+  Py_XDECREF(_pickler);
+}
diff --git a/src/Container/SALOME_CPythonHelper.hxx b/src/Container/SALOME_CPythonHelper.hxx
new file mode 100644 (file)
index 0000000..b6c4713
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright (C) 2019  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#pragma once
+
+#include "SALOME_Container.hxx"
+
+#include "Python.h"
+
+#include <string>
+#include <vector>
+
+class CONTAINER_EXPORT SALOME_CPythonHelper
+{
+ public:
+  void initializePython(int argc, char *argv[]);
+  void registerToSalomePiDict(const std::string& processName, long pid) const;
+  std::vector<long> evalVL(const std::string& pyCode) const;
+  std::string evalS(const std::string& pyCode) const;
+  virtual ~SALOME_CPythonHelper();
+  PyObject *getGlobals() const { return _globals; }
+  PyObject *getLocals() const { return _locals; }
+  PyObject *getPickler() const  { return _pickler; }
+ private:
+  PyObject *_globals = nullptr;
+  PyObject *_locals = nullptr;
+  PyObject *_pickler = nullptr;
+  PyObject *_subprocess = nullptr;
+};
index bd274d45f8f2d1b768e5849f90b9a28808b001a6..c50c8c0f81ed0ed45fa4831c20a7a35bbe094b4f 100644 (file)
@@ -1399,6 +1399,34 @@ int SALOME_ContainerManager::SystemThreadSafe(const char *command)
   return system(command);
 }
 
+long SALOME_ContainerManager::SystemWithPIDThreadSafe(const std::vector<std::string>& command)
+{
+  Utils_Locker lock(&_systemMutex);
+  if(command.size()<1)
+    throw SALOME_Exception("SystemWithPIDThreadSafe : command is expected to have a length of size 1 at least !");
+  pid_t pid ( fork() ) ; // spawn a child process, following code is executed in both processes
+  if ( pid == 0 ) // I'm a child, replace myself with a new ompi-server
+    {
+      std::size_t sz(command.size()-1);
+      char **args = new char *[sz+1];
+      for(std::size_t i=0;i<sz;i++)
+        args[i] = strdup(command[i+1].c_str());
+      args[sz] = nullptr;
+      execvp( command[0].c_str() , args );
+      std::ostringstream oss;
+      oss << "Error when launching " << command[0];
+      throw SALOME_Exception(oss.str().c_str()); // execvp failed
+    }
+  else if ( pid < 0 )
+    {
+      throw SALOME_Exception("fork() failed");
+    }
+  else // I'm a parent
+    {
+      return pid;
+    }
+}
+
 #ifdef WITH_PACO_PARALLEL
 
 //=============================================================================
index 941603e936d88a7a4a939af654a6a1e0b39604d5..c733b90ecce086d3ce48c18bd5f69800412c7d38 100644 (file)
@@ -162,6 +162,7 @@ public:
   static char *GetenvThreadSafe(const char *name);
   static std::string GetenvThreadSafeAsString(const char *name);
   static int SystemThreadSafe(const char *command);
+  static long SystemWithPIDThreadSafe(const std::vector<std::string>& command);
   static void AddOmninamesParams(std::ostream& fileStream, SALOME_NamingService *ns);
   static void MakeTheCommandToBeLaunchedASync(std::string& command);
   static int GetTimeOutToLoaunchServer();
index 0d2f77497805100a1791e3d7c243fa0d2454b166..4ac646bcc0fb1b575133f237b1b0b82b025cfbf5 100644 (file)
@@ -161,8 +161,8 @@ if not flags:
 #    sys.setdlopenflags(flags)
 #    pass
 
-orb, lcc, naming_service, cm,sg=None,None,None,None,None
-myStudy, myStudyName=None,None
+orb, lcc, naming_service, cm, sg, esm = None,None,None,None,None,None
+myStudy, myStudyName = None,None
 
 salome_initial=True
 def salome_init(path=None, embedded=False):
@@ -173,12 +173,13 @@ def salome_init(path=None, embedded=False):
     lcc             a LifeCycleCorba instance
     naming_service  a naming service instance
     cm              reference to the container manager
+    esm             reference to external server manager
     sg              access to SALOME GUI (when linked with IAPP GUI)
     myStudy         active study itself (CORBA reference)
     myStudyName     active study name
     """
     global salome_initial
-    global orb, lcc, naming_service, cm
+    global orb, lcc, naming_service, cm, esm
     global sg
     global myStudy, myStudyName
 
@@ -186,7 +187,7 @@ def salome_init(path=None, embedded=False):
         if salome_initial:
             salome_initial=False
             sg = salome_iapp_init(embedded)
-            orb, lcc, naming_service, cm = salome_kernel_init()
+            orb, lcc, naming_service, cm, esm = salome_kernel_init()
             myStudy, myStudyName = salome_study_init(path)
             pass
         pass
index a5a93eb8fe8d415579260da279ac8f0679f27e13..098d2d9f22cd53cf732f8755346d5e8bc3d40949 100644 (file)
@@ -31,14 +31,16 @@ from LifeCycleCORBA import *
 from SALOME_NamingServicePy import *
 from SALOME_utilities import *
 import Engines
+import SALOME
 
 orb = None
 lcc = None
 naming_service = None
 cm = None
+esm = None
 
 def salome_kernel_init():
-    global orb, lcc, naming_service, cm
+    global orb, lcc, naming_service, cm, esm
     
     if not orb:
         # initialise the ORB
@@ -53,5 +55,8 @@ def salome_kernel_init():
         # get Container Manager
         obj = naming_service.Resolve('/ContainerManager')
         cm = obj._narrow(Engines.ContainerManager)
-
-    return orb, lcc, naming_service, cm
+        # get External Server Manager
+        obj = naming_service.Resolve('/ExternalServers')
+        esm = obj._narrow(SALOME.ExternalServerLauncher)
+        
+    return orb, lcc, naming_service, cm, esm
index 67f3c9db074427936d62c82b6aa83d2c01741ca3..b2574c66c5f83f17ccae803d74489edd49564865 100644 (file)
@@ -292,7 +292,7 @@ def salome_study_init(theStudyPath=None):
 
     if verbose(): print("theStudyPath:", theStudyPath)
     if not myStudy:
-        orb, lcc, naming_service, cm = salome_kernel.salome_kernel_init()
+        orb, lcc, naming_service, cm, _ = salome_kernel.salome_kernel_init()
 
         # get Study reference
         if verbose(): print("looking for study...")
index 09228204d53b0ca357968ce0efb9af86bdd2743d..9cf21a335d93021dc00512a37266ceba27cd75dd 100644 (file)
@@ -96,7 +96,7 @@ ADD_EXECUTABLE(TestLauncher TestLauncher.cxx)
 TARGET_LINK_LIBRARIES(TestLauncher ${TestLauncher_LIBS})
 INSTALL(TARGETS TestLauncher DESTINATION ${SALOME_INSTALL_BINS})
 
-ADD_LIBRARY(SalomeLauncher BatchTest.cxx SALOME_Launcher.cxx)
+ADD_LIBRARY(SalomeLauncher BatchTest.cxx SALOME_Launcher.cxx SALOME_ExternalServerLauncher.cxx SALOME_LauncherException.cxx SALOME_ExternalServerHandler.cxx)
 TARGET_LINK_LIBRARIES(SalomeLauncher Launcher ${COMMON_LIBS})
 INSTALL(TARGETS SalomeLauncher EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS})
   
@@ -129,6 +129,8 @@ SET(COMMON_HEADERS_HXX
   SALOME_Launcher.hxx
   SALOME_Launcher_Parser.hxx
   SALOME_Launcher_defs.hxx
+  SALOME_ExternalServerLauncher.hxx
+  SALOME_LauncherException.hxx
 )
 
 SET(LAUNCHER_PYTHON_SCRIPTS
diff --git a/src/Launcher/SALOME_ExternalServerHandler.cxx b/src/Launcher/SALOME_ExternalServerHandler.cxx
new file mode 100644 (file)
index 0000000..ddda9a7
--- /dev/null
@@ -0,0 +1,129 @@
+// Copyright (C) 2019  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#include "SALOME_ExternalServerHandler.hxx"
+#include "SALOME_ExternalServerLauncher.hxx"
+#include "SALOME_NamingService.hxx"
+#include "SALOME_LauncherException.hxx"
+#include "SALOME_ContainerManager.hxx"
+#include "SALOME_CPythonHelper.hxx"
+
+#include <sstream>
+#include <fstream>
+#include <algorithm>
+
+#ifndef WIN32
+#include <sys/types.h>
+#include <signal.h>
+#endif
+
+unsigned SALOME_ExternalServerHandler::CNT = 0;
+
+SALOME_ExternalServerHandler::SALOME_ExternalServerHandler(SALOME_ExternalServerLauncher *boss, const std::string& name, SALOME_NamingService *ns, long pid):_name(name),_pid(pid),_NS(ns),_boss(boss)
+{
+}
+
+SALOME_ExternalServerHandler::~SALOME_ExternalServerHandler()
+{
+}
+
+void SALOME_ExternalServerHandler::registerToKill(const SALOME_CPythonHelper *pyHelper) const
+{
+  std::ostringstream oss;
+  oss << _name << "_" << CNT++;
+  pyHelper->registerToSalomePiDict(oss.str(),_pid);
+}
+
+CORBA::Long SALOME_ExternalServerHandler::getPID()
+{
+  return _pid;
+}
+
+char *SALOME_ExternalServerHandler::getName()
+{
+  return CORBA::string_dup(_name.c_str());
+}
+
+void SALOME_ExternalServerHandler::killMe()
+{
+#ifndef WIN32
+  kill(_pid,SIGTERM);//SIGTERM is emitted not SIGKILL to give _pid process a chance to trap it.
+#endif
+}
+
+void SALOME_ExternalServerHandler::ping()
+{
+#ifndef WIN32
+  if( kill(_pid,0) != 0 )
+    {
+      std::ostringstream oss2; oss2 << "SALOME_ExternalServerHandler::ping : Fail to ping server " << _name << "\" with pid = " << _pid << " !";
+      throw SALOME_LauncherException(oss2.str());
+    }
+  // check for a non zombie process
+  std::ostringstream statusFile;
+  statusFile << "/proc/" << _pid << "/status";
+  std::ifstream ifs(statusFile.str());
+  if(!ifs.good())
+    {
+      std::ostringstream oss2; oss2 << "SALOME_ExternalServerHandler::ping : Fail to ping server " << _name << "\" with pid = " << _pid << " during access of status file !";
+      throw SALOME_LauncherException(oss2.str());
+    }
+  constexpr char PAT[]="State:";
+  while(ifs.good())
+    {
+      std::string line;
+      std::getline(ifs,line);
+      if(line.substr(0,strlen(PAT))==PAT)
+        {
+          std::string part2(line.substr(strlen(PAT)));
+          std::size_t pos(part2.find_first_not_of(" \t"));
+          if(pos==std::string::npos)
+            return ;
+          char state(part2[pos]);
+          if(state!='Z')
+            return ;
+          std::ostringstream oss2; oss2 << "SALOME_ExternalServerHandler::ping : server " << _name << "\" with pid = " << _pid << " has been detected as a Zombie !";
+          throw SALOME_LauncherException(oss2.str());
+        }
+    }
+#endif
+}
+
+void SALOME_ExternalServerHandler::shutdown()
+{
+  killMe();
+  _boss->cleanServersInNS();
+}
+
+SALOME::LongVec *SALOME_ExternalServerHandler::listOfChildrenPID()
+{
+  SALOME::LongVec *ret(new SALOME::LongVec);
+  const SALOME_CPythonHelper *pyh(_boss->getPyHelper());
+#ifndef WIN32
+  std::ostringstream oss;
+  oss << "[int(elt) for elt in sp.check_output([\"ps\",\"-o\",\"pid=\",\"--ppid\",\"" << _pid << "\"]).split()]";
+  std::vector<long> pids(pyh->evalVL(oss.str()));
+  std::size_t sz(pids.size());
+  ret->length(sz);
+  for(auto i=0;i<sz;i++)
+    (*ret)[i] = pids[i];
+#endif
+  return ret;
+}
diff --git a/src/Launcher/SALOME_ExternalServerHandler.hxx b/src/Launcher/SALOME_ExternalServerHandler.hxx
new file mode 100644 (file)
index 0000000..045ec4c
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2019  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#pragma once
+
+#include "SALOME_Launcher_defs.hxx"
+
+#include <SALOMEconfig.h>
+
+#include CORBA_SERVER_HEADER(SALOME_ExternalServerLauncher)
+
+#include <string>
+
+class SALOME_NamingService;
+class SALOME_ExternalServerLauncher;
+class SALOME_CPythonHelper;
+
+class SALOMELAUNCHER_EXPORT SALOME_ExternalServerHandler : public POA_SALOME::ExternalServerHandler
+{
+ public:
+  SALOME_ExternalServerHandler(SALOME_ExternalServerLauncher *boss, const std::string& name, SALOME_NamingService *ns, long pid);
+  virtual ~SALOME_ExternalServerHandler();
+  void registerToKill(const SALOME_CPythonHelper *pyHelper) const;
+ public:
+  CORBA::Long getPID() override;
+  char *getName() override;
+  void killMe() override;
+  void ping() override;
+  void shutdown() override;
+  SALOME::LongVec *listOfChildrenPID() override;
+ private:
+  std::string _name;
+  long _pid;
+  SALOME_NamingService *_NS;
+  SALOME_ExternalServerLauncher *_boss;
+  static unsigned CNT;
+};
diff --git a/src/Launcher/SALOME_ExternalServerLauncher.cxx b/src/Launcher/SALOME_ExternalServerLauncher.cxx
new file mode 100644 (file)
index 0000000..39ff157
--- /dev/null
@@ -0,0 +1,191 @@
+// Copyright (C) 2019  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#include "SALOME_ExternalServerLauncher.hxx"
+#include "SALOME_ExternalServerHandler.hxx"
+#include "SALOME_NamingService.hxx"
+#include "SALOME_LauncherException.hxx"
+#include "SALOME_ContainerManager.hxx"
+#include "SALOME_CPythonHelper.hxx"
+
+#include CORBA_CLIENT_HEADER(SALOME_ExternalServerLauncher)
+
+#include <sstream>
+#include <algorithm>
+
+constexpr char NAME_IN_NS[]="/ExternalServers";
+
+unsigned SALOME_ExternalServerLauncher::CNT = 0;
+
+SALOME_ExternalServerLauncher::SALOME_ExternalServerLauncher(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, PortableServer::POA_var poa):_pyHelper(pyHelper),_poa(poa)
+{
+  _NS = new SALOME_NamingService(orb);
+  PortableServer::ObjectId_var id(_poa->activate_object(this));
+  CORBA::Object_var obj(_poa->id_to_reference(id));
+  SALOME::ExternalServerLauncher_var refPtr(SALOME::ExternalServerLauncher::_narrow(obj));
+  _NS->Register(refPtr,NAME_IN_NS);
+}
+
+SALOME_ExternalServerLauncher::~SALOME_ExternalServerLauncher()
+{
+  delete _NS;
+}
+
+SALOME::ExternalServerHandler_ptr SALOME_ExternalServerLauncher::launchServer(const char *server_name, const SALOME::CmdList& command_list )
+{
+  std::vector<std::string> servers(ListOfExternalServersCpp(_NS));
+  if(std::find(servers.begin(),servers.end(),server_name)!=servers.end())
+    {
+      std::ostringstream oss2; oss2 << "SALOME_ExternalServerLauncher::launchServer : Server \""<< server_name << "\" already exists !";
+      throw SALOME_LauncherException(oss2.str());
+    }
+  std::vector<std::string> cmd(command_list.length());
+  const char *toto(command_list[0]);
+  for(auto i=0;i<command_list.length();i++)
+    cmd[i] = command_list[i];
+  long pid(0);
+  try
+    {
+      pid = SALOME_ContainerManager::SystemWithPIDThreadSafe(cmd) ;
+    }
+  catch(SALOME_Exception& e)
+    {
+      std::ostringstream oss2; oss2 << "SALOME_ExternalServerLauncher::launchServer : Fail to launch subprocess ! Reason is : " << e.what() << " !";
+      throw SALOME_LauncherException(oss2.str());
+    }
+  SALOME_ExternalServerHandler *retServ(new SALOME_ExternalServerHandler(this,server_name,_NS,pid));
+  retServ->registerToKill(_pyHelper);
+  PortableServer::ObjectId_var id(_poa->activate_object(retServ));
+  CORBA::Object_var obj(_poa->id_to_reference(id));
+  std::string fullServerName(CreateAbsNameInNSFromServerName(server_name));
+  SALOME::ExternalServerHandler_ptr ret(SALOME::ExternalServerHandler::_narrow(obj));
+  _NS->Register(ret,fullServerName.c_str());
+  return ret;
+}
+
+void SALOME_ExternalServerLauncher::registerToKill(const char *server_name, CORBA::Long PID)
+{
+  std::ostringstream oss;
+  oss << "Custom_"<< server_name << "_" << CNT++;
+  _pyHelper->registerToSalomePiDict(oss.str(),PID);
+}
+
+void SALOME_ExternalServerLauncher::cleanServersInNS()
+{
+  std::vector<std::string> servers(ListOfExternalServersCpp(_NS));
+  for(std::vector<std::string>::const_iterator it=servers.begin();it!=servers.end();it++)
+    {
+      if(!IsAliveAndKicking(_NS,(*it).c_str()))
+        {
+          std::string fullServerName(CreateAbsNameInNSFromServerName(*it));
+          _NS->Destroy_Name(fullServerName.c_str());
+        }
+    }
+}
+
+void SALOME_ExternalServerLauncher::shutdownServers()
+{
+  std::vector<std::string> lioes(ListOfExternalServersCpp(_NS));
+  for(auto servName : lioes)
+    {
+      SALOME::ExternalServerHandler_var proc(GetServerHandlerGivenName(_NS,servName));
+      PortableServer::ServantBase *procServ(_poa->reference_to_servant(proc));
+      SALOME_ExternalServerHandler *procServC(dynamic_cast<SALOME_ExternalServerHandler *>(procServ));
+      try
+        {
+          procServC->killMe();
+        }
+      catch(...)
+        { }
+    }
+  cleanServersInNS();
+}
+
+SALOME::StringVec *SALOME_ExternalServerLauncher::listServersInNS()
+{
+  SALOME::StringVec *ret(new SALOME::StringVec);
+  std::vector<std::string> loes(ListOfExternalServersCpp(_NS));
+  std::size_t sz(loes.size());
+  ret->length(sz);
+  for(auto i = 0; i<sz ; i++)
+    {
+      (*ret)[i]=CORBA::string_dup(loes[i].c_str());
+    }
+  return ret;
+}
+
+SALOME::ExternalServerHandler_ptr SALOME_ExternalServerLauncher::retrieveServerRefGivenNSEntry( const char *ns_entry )
+{
+  SALOME::ExternalServerHandler_var ret(GetServerHandlerGivenName(_NS,ns_entry));
+  return ret._retn();
+}
+
+char *SALOME_ExternalServerLauncher::gethostname()
+{
+  std::string ret(_pyHelper->evalS("socket.gethostname()"));
+  return CORBA::string_dup(ret.c_str());
+}
+
+std::vector<std::string> SALOME_ExternalServerLauncher::ListOfExternalServersCpp(SALOME_NamingService *ns)
+{
+  ns->Change_Directory(NAME_IN_NS);
+  std::vector<std::string> ret(ns->list_directory());
+  return ret;
+}
+
+std::string SALOME_ExternalServerLauncher::CreateAbsNameInNSFromServerName(const std::string& scopeName)
+{
+  std::ostringstream oss; oss << NAME_IN_NS << "/" << scopeName;
+  return oss.str();
+}
+
+bool SALOME_ExternalServerLauncher::IsAliveAndKicking(SALOME::ExternalServerHandler_ptr server)
+{
+  bool ret(true);
+  try
+    {
+      server->ping();
+    }
+  catch(...)
+    { ret=false; }
+  return ret;
+}
+
+bool SALOME_ExternalServerLauncher::IsAliveAndKicking(SALOME_NamingService *ns, const std::string& serverName)
+{
+  SALOME::ExternalServerHandler_var pt(GetServerHandlerGivenName(ns, serverName));
+  if( CORBA::is_nil(pt) )
+    return false;
+  return IsAliveAndKicking(pt);
+}
+
+SALOME::ExternalServerHandler_var SALOME_ExternalServerLauncher::GetServerHandlerGivenName(SALOME_NamingService *ns, const std::string& serverName)
+{
+  std::vector<std::string> serverNames(ListOfExternalServersCpp(ns));
+  if(std::find(serverNames.begin(),serverNames.end(),serverName)==serverNames.end())
+    {
+      std::ostringstream oss; oss << "SALOME_ExternalServerLauncher::GetServerHandlerGivenName : scope name \"" << serverName << "\" does not exist !";
+      throw SALOME_LauncherException(oss.str());
+    }
+  std::string fullServerName(CreateAbsNameInNSFromServerName(serverName));
+  CORBA::Object_var obj(ns->Resolve(fullServerName.c_str()));
+  SALOME::ExternalServerHandler_var ret(SALOME::ExternalServerHandler::_narrow(obj));
+  return ret;
+}
diff --git a/src/Launcher/SALOME_ExternalServerLauncher.hxx b/src/Launcher/SALOME_ExternalServerLauncher.hxx
new file mode 100644 (file)
index 0000000..474949d
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2019  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#pragma once
+
+#include "SALOME_Launcher_defs.hxx"
+
+#include <SALOMEconfig.h>
+
+#include CORBA_SERVER_HEADER(SALOME_ExternalServerLauncher)
+
+#include <vector>
+#include <string>
+
+class SALOME_NamingService;
+class SALOME_CPythonHelper;
+
+class SALOMELAUNCHER_EXPORT SALOME_ExternalServerLauncher : public POA_SALOME::ExternalServerLauncher
+{
+ public:
+  SALOME_ExternalServerLauncher(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, PortableServer::POA_var poa);
+  virtual ~SALOME_ExternalServerLauncher();
+ public:
+  SALOME::ExternalServerHandler_ptr launchServer(const char *server_name, const SALOME::CmdList& command_list ) override;
+  void registerToKill(const char *server_name, CORBA::Long PID) override;
+  void cleanServersInNS() override;
+  void shutdownServers() override;
+  SALOME::StringVec *listServersInNS() override;
+  SALOME::ExternalServerHandler_ptr retrieveServerRefGivenNSEntry( const char *ns_entry ) override;
+  char *gethostname() override;
+  const SALOME_CPythonHelper *getPyHelper() const { return _pyHelper; }
+ private:
+  static std::string CreateAbsNameInNSFromServerName(const std::string& scopeName);
+  static std::vector<std::string> ListOfExternalServersCpp(SALOME_NamingService *ns);
+  static bool IsAliveAndKicking(SALOME::ExternalServerHandler_ptr server);
+  static bool IsAliveAndKicking(SALOME_NamingService *ns, const std::string& serverName);
+  static SALOME::ExternalServerHandler_var GetServerHandlerGivenName(SALOME_NamingService *ns, const std::string& serverName);
+ private:
+  const SALOME_CPythonHelper *_pyHelper = nullptr;
+  SALOME_NamingService *_NS = nullptr;
+  PortableServer::POA_var _poa;
+  static unsigned CNT;
+};
diff --git a/src/Launcher/SALOME_LauncherException.cxx b/src/Launcher/SALOME_LauncherException.cxx
new file mode 100644 (file)
index 0000000..5f5bf7f
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright (C) 2019  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#include "SALOME_LauncherException.hxx"
+
+SALOME_LauncherException::SALOME_LauncherException(const std::string& reason)
+{
+  this->assign(reason.c_str());
+}
+
+SALOME_LauncherException::SALOME_LauncherException(const char *reason)
+{
+  this->assign(reason);
+}
+
+void SALOME_LauncherException::assign(const char *reason)
+{
+  SALOME::ExceptionStruct es;
+  es.type=SALOME::INTERNAL_ERROR;
+  es.text=CORBA::string_dup(reason);
+  es.lineNumber=0;
+  (*this).details=es;
+}
diff --git a/src/Launcher/SALOME_LauncherException.hxx b/src/Launcher/SALOME_LauncherException.hxx
new file mode 100644 (file)
index 0000000..7649553
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright (C) 2019  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#pragma once
+
+#include "SALOME_Launcher_defs.hxx"
+
+#include "SALOMEconfig.h"
+#include CORBA_SERVER_HEADER(SALOME_Exception)
+
+#include "SALOMESDS_Defines.hxx"
+
+#include <string>
+
+class SALOMELAUNCHER_EXPORT SALOME_LauncherException : public SALOME::SALOME_Exception
+{
+ public:
+  SALOME_LauncherException(const std::string& reason);
+  SALOME_LauncherException(const char *reason);
+ private:
+  void assign(const char *reason);
+};
index 106e9d28774195f13f8cd35d8a02ee14181b0ae9..91b51d2e913236451daaeabb3d63bd8ab08f3c65 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "SALOME_Launcher.hxx"
 #include "SALOMESDS_DataServerManager.hxx"
+#include "SALOME_ExternalServerLauncher.hxx"
+#include "SALOME_CPythonHelper.hxx"
 #include "utilities.h"
 #include <sstream>
 #include <iostream>
@@ -113,13 +115,17 @@ int main(int argc, char* argv[])
       policies[0] = PortableServer::ThreadPolicy::_duplicate(threadPol);
       PortableServer::POA_var safePOA = root_poa->create_POA("SingleThreadPOA",pman,policies);
       threadPol->destroy();
-
+      SALOME_CPythonHelper cPyh;
+      cPyh.initializePython(argc,argv);
       SALOME_Launcher *lServ(new SALOME_Launcher(orb,safePOA));
       lServ->_remove_ref();
       //
-      SALOMESDS::DataServerManager *dsm(new SALOMESDS::DataServerManager(argc,argv,orb,root_poa));
+      SALOMESDS::DataServerManager *dsm(new SALOMESDS::DataServerManager(&cPyh,orb,root_poa));
       dsm->_remove_ref();
       //
+      SALOME_ExternalServerLauncher *esm(new SALOME_ExternalServerLauncher(&cPyh,orb,safePOA));
+      esm->_remove_ref();
+      //
       orb->run();
       orb->destroy();
     }
index 3fd917e556288f94935dcf16606c3c6c6273d6d7..789b0b2a0fa8967d62b46d4a34a19f1c568596e1 100644 (file)
@@ -26,6 +26,7 @@ INCLUDE_DIRECTORIES(
   ${PROJECT_BINARY_DIR}/salome_adm
   ${CMAKE_CURRENT_SOURCE_DIR}/../Utils
   ${CMAKE_CURRENT_SOURCE_DIR}/../NamingService
+  ${CMAKE_CURRENT_SOURCE_DIR}/../Launcher
   ${CMAKE_CURRENT_SOURCE_DIR}/../Container
   ${CMAKE_CURRENT_SOURCE_DIR}/../ResourcesManager
 )
index d77de5e6da26ebfb4d98855c1ecffcf1720985da..cd10634f48b7e5385430ee7ba7fd5153851dcfb1 100644 (file)
@@ -46,19 +46,6 @@ using namespace SALOMESDS;
 
 std::size_t DataScopeServerBase::COUNTER=0;
 
-#if PY_VERSION_HEX < 0x03050000
-static char*
-Py_EncodeLocale(const wchar_t *arg, size_t *size)
-{
-       return _Py_wchar2char(arg, size);
-}
-static wchar_t*
-Py_DecodeLocale(const char *arg, size_t *size)
-{
-       return _Py_char2wchar(arg, size);
-}
-#endif
-
 void DataScopeKiller::shutdown()
 {
   Py_Finalize();
@@ -84,19 +71,16 @@ void RequestSwitcher::fetchAndGetAccessOfVar(const char *varName, CORBA::String_
   return _ds->fetchAndGetAccessOfVar(varName,access,data);
 }
 
-DataScopeServerBase::DataScopeServerBase(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):_globals(0),_locals(0),_pickler(0),_orb(CORBA::ORB::_duplicate(orb)),_name(scopeName),_killer(killer)
+DataScopeServerBase::DataScopeServerBase(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):_pyHelper(pyHelper),_orb(CORBA::ORB::_duplicate(orb)),_name(scopeName),_killer(killer)
 {
 }
 
-DataScopeServerBase::DataScopeServerBase(const DataScopeServerBase& other):omniServant(other),ServantBase(other),_globals(0),_locals(0),_pickler(0),_name(other._name),_vars(other._vars),_killer(other._killer)
+DataScopeServerBase::DataScopeServerBase(const DataScopeServerBase& other):omniServant(other),ServantBase(other),_pyHelper(other._pyHelper),_name(other._name),_vars(other._vars),_killer(other._killer)
 {
 }
 
 DataScopeServerBase::~DataScopeServerBase()
 {
-  // _globals is borrowed ref -> do nothing
-  Py_XDECREF(_locals);
-  Py_XDECREF(_pickler);
   for(std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it=_vars.begin();it!=_vars.end();it++)
     {
        BasicDataServer *obj((*it).second);
@@ -276,44 +260,9 @@ void DataScopeServerBase::takeANap(CORBA::Double napDurationInSec)
 #endif
 }
 
-void DataScopeServerBase::initializePython(int argc, char *argv[])
-{
-  Py_Initialize();
-  PyEval_InitThreads();
-  wchar_t **changed_argv = new wchar_t*[argc]; // Setting arguments
-  for (int i = 0; i < argc; i++)
-    changed_argv[i] = Py_DecodeLocale(argv[i], NULL);
-  PySys_SetArgv(argc, changed_argv);
-  PyObject *mainmod(PyImport_AddModule("__main__"));
-  _globals=PyModule_GetDict(mainmod);
-  if(PyDict_GetItemString(_globals, "__builtins__") == NULL)
-    {
-      PyObject *bimod(PyImport_ImportModule("__builtin__"));
-      if (bimod == NULL || PyDict_SetItemString(_globals, "__builtins__", bimod) != 0)
-        Py_FatalError("can't add __builtins__ to __main__");
-      Py_XDECREF(bimod);
-    }
-  _locals=PyDict_New();
-  PyObject *tmp(PyList_New(0));
-  _pickler=PyImport_ImportModuleLevel(const_cast<char *>("pickle"),_globals,_locals,tmp,0);
-}
-
 void DataScopeServerBase::registerToSalomePiDict() const
 {
-  PyObject *mod(PyImport_ImportModule("addToKillList"));//new value
-  if(!mod)
-    return;
-  PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));//new value
-  if(!meth)
-    { Py_XDECREF(mod); return ; }
-  PyObject *args(PyTuple_New(2));
-  PyTuple_SetItem(args,0,PyLong_FromLong(getpid()));
-  PyTuple_SetItem(args,1,PyUnicode_FromString("SALOME_DataScopeServerBase"));
-  PyObject *res(PyObject_CallObject(meth,args));
-  Py_XDECREF(args);
-  Py_XDECREF(res);
-  Py_XDECREF(meth);
-  Py_XDECREF(mod);
+  _pyHelper->registerToSalomePiDict("SALOME_DataScopeServerBase",getpid());
 }
 
 void DataScopeServerBase::setPOA(PortableServer::POA_var poa)
@@ -496,7 +445,7 @@ std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterat
 
 ///////
 
-DataScopeServer::DataScopeServer(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
+DataScopeServer::DataScopeServer(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(pyHelper,orb,killer,scopeName)
 {
 }
 
@@ -543,7 +492,7 @@ DataScopeServer::~DataScopeServer()
 
 ////////
 
-DataScopeServerTransaction::DataScopeServerTransaction(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
+DataScopeServerTransaction::DataScopeServerTransaction(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(pyHelper,orb,killer,scopeName)
 {
   CORBA::Object_var obj(_orb->resolve_initial_references("RootPOA"));
   PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
index 96649df2fec5f7d5d78f4ec8aae41b57ecd2c1b2..9eb65b8ce2a43fe8109786b1e9eb946b0bd3e7c0 100644 (file)
@@ -30,6 +30,7 @@
 #include "SALOMESDS_BasicDataServer.hxx"
 #include "SALOMESDS_Auto.hxx"
 #include "SALOMESDS_Defines.hxx"
+#include "SALOME_CPythonHelper.hxx"
 
 #include <Python.h>
 
@@ -72,7 +73,7 @@ namespace SALOMESDS
   class SALOMESDS_EXPORT DataScopeServerBase : public virtual POA_SALOME::DataScopeServerBase, public POAHolder
   {
   public:
-    DataScopeServerBase(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName);
+    DataScopeServerBase(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName);
     DataScopeServerBase(const DataScopeServerBase& other);
   public: // remote access methods
     void ping();
@@ -88,13 +89,12 @@ namespace SALOMESDS
   public:
     ~DataScopeServerBase();
     BasicDataServer *retrieveVarInternal2(const std::string& varName);
-    void initializePython(int argc, char *argv[]);
     void registerToSalomePiDict() const;
     void setPOA(PortableServer::POA_var poa);
     void registerInNS(SALOME::DataScopeServerBase_ptr ptr);
-    PyObject *getGlobals() const { return _globals; }
-    PyObject *getLocals() const { return _locals; }
-    PyObject *getPickler() const { return _pickler; }
+    PyObject *getGlobals() const { return _pyHelper->getGlobals(); }
+    PyObject *getLocals() const { return _pyHelper->getLocals(); }
+    PyObject *getPickler() const { return _pyHelper->getPickler(); }
     PortableServer::POA_var getPOA() const { return _poa; }
     CORBA::ORB_var getORB() { return _orb; }
     std::string getScopeNameCpp() const { return _name; }
@@ -114,9 +114,7 @@ namespace SALOMESDS
     std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator retrieveVarInternal3(const std::string& varName) const;
     std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator retrieveVarInternal4(const std::string& varName);
   protected:
-    PyObject *_globals;
-    PyObject *_locals;
-    PyObject *_pickler;
+    const SALOME_CPythonHelper *_pyHelper = nullptr;
     PortableServer::POA_var _poa;
     CORBA::ORB_var _orb;
     std::string _name;
@@ -128,7 +126,7 @@ namespace SALOMESDS
   class SALOMESDS_EXPORT DataScopeServer : public DataScopeServerBase, public virtual POA_SALOME::DataScopeServer
   {
   public:
-    DataScopeServer(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName);
+    DataScopeServer(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName);
     DataScopeServer(const DataScopeServer& other);
     SALOME::BasicDataServer_ptr retrieveVar(const char *varName) { return retrieveVarInternal(varName); }
     SALOME::PickelizedPyObjRdOnlyServer_ptr createRdOnlyVar(const char *varName, const SALOME::ByteVec& constValue);
@@ -140,7 +138,7 @@ namespace SALOMESDS
   class SALOMESDS_EXPORT DataScopeServerTransaction : public DataScopeServerBase, public virtual POA_SALOME::DataScopeServerTransaction
   {
   public://not remotely callable
-    DataScopeServerTransaction(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName);
+    DataScopeServerTransaction(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName);
     DataScopeServerTransaction(const DataScopeServerTransaction& other);
     ~DataScopeServerTransaction();
     void createRdOnlyVarInternal(const std::string& varName, const SALOME::ByteVec& constValue);
index 3e60a350b0750681155d2a66a23ea52f57a55016..1e920c65d1ff60c3df32a2ac528a8d1f339b2b5e 100644 (file)
@@ -43,9 +43,9 @@ SALOME::DataScopeServerTransaction_ptr RequestSwitcherDSM::giveADataScopeTransac
   return _dsm->giveADataScopeTransactionCalled(scopeName,isCreated);
 }
 
-DataServerManager::DataServerManager(int argc, char *argv[], CORBA::ORB_ptr orb, PortableServer::POA_ptr poa):_orb(CORBA::ORB::_duplicate(orb))
+DataServerManager::DataServerManager(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, PortableServer::POA_ptr poa):_orb(CORBA::ORB::_duplicate(orb))
 {
-  DataScopeServer *dftScope(new DataScopeServer(orb,SALOME::DataScopeKiller::_nil(),DFT_SCOPE_NAME_IN_NS));//_remove_ref will be call by DataScopeServer::shutdownIfNotHostedByDSM
+  DataScopeServer *dftScope(new DataScopeServer(pyHelper,orb,SALOME::DataScopeKiller::_nil(),DFT_SCOPE_NAME_IN_NS));//_remove_ref will be call by DataScopeServer::shutdownIfNotHostedByDSM
   PortableServer::POAManager_var pman(poa->the_POAManager());
   CORBA::PolicyList policies;
   policies.length(1);
@@ -53,8 +53,6 @@ DataServerManager::DataServerManager(int argc, char *argv[], CORBA::ORB_ptr orb,
   policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
   _poa=poa->create_POA("SingleThPOA4SDS",pman,policies);
   threadPol->destroy();
-  //
-  dftScope->initializePython(argc,argv);// agy : Very important ! invoke this method BEFORE activation !
   // activate this to be ready to be usable from NS.
   PortableServer::ObjectId_var id(_poa->activate_object(this));
   CORBA::Object_var obj(_poa->id_to_reference(id));
index a9c99962965fc9eec63b6b3585a626a8d55c64f3..cf95642c046bf0b5ba0faf9c9a7c8f6c96d5f284 100644 (file)
@@ -53,7 +53,7 @@ namespace SALOMESDS
   class SALOMESDS_EXPORT DataServerManager : public virtual POA_SALOME::DataServerManager
   {
   public:
-    DataServerManager(int argc, char *argv[], CORBA::ORB_ptr orb, PortableServer::POA_ptr poa);
+    DataServerManager(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, PortableServer::POA_ptr poa);
     SALOME::StringVec *listScopes();
     SALOME::StringVec *listAliveAndKickingScopes();
     SALOME::DataScopeServer_ptr getDefaultScope();
index 4fb8a250f269cb544ed2ce75067199bcb9a686a6..9ab6eb0dcfb9006f8b128553a2e0c54190524439 100644 (file)
@@ -21,6 +21,7 @@
 #include "SALOMESDS_DataScopeServer.hxx"
 #include "SALOMESDS_DataServerManager.hxx"
 #include "SALOMESDS_Exception.hxx"
+#include "SALOME_CPythonHelper.hxx"
 
 #include "SALOME_NamingService.hxx"
 
@@ -56,11 +57,14 @@ int main(int argc, char *argv[])
   SALOMESDS::DataScopeKiller *killer(new SALOMESDS::DataScopeKiller(orb));
   SALOME::DataScopeKiller_var killerObj(killer->_this());
   //
-  SALOMESDS::DataScopeServerBase *server(0);
+  SALOME_CPythonHelper cPyHelper;
+  cPyHelper.initializePython(argc,argv);
+  //
+  SALOMESDS::DataScopeServerBase *server(nullptr);
   if(!isTransac)
-    server=new SALOMESDS::DataScopeServer(orb,killerObj,scopeName);
+    server=new SALOMESDS::DataScopeServer(&cPyHelper,orb,killerObj,scopeName);
   else
-    server=new SALOMESDS::DataScopeServerTransaction(orb,killerObj,scopeName);
+    server=new SALOMESDS::DataScopeServerTransaction(&cPyHelper,orb,killerObj,scopeName);
   //
   CORBA::PolicyList policies;
   policies.length(3);
@@ -70,7 +74,6 @@ int main(int argc, char *argv[])
   policies[2]=poa->create_id_uniqueness_policy(PortableServer::UNIQUE_ID);
   PortableServer::POA_var poa2(poa->create_POA("SingleThPOA4SDS",mgr,policies));
   threadPol->destroy();
-  server->initializePython(argc,argv);// agy : Very important ! invoke this method BEFORE activation !
   server->registerToSalomePiDict();
   //
   server->setPOA(poa2);