Salome HOME
PR: compatibility with Supervision, use new Python thread states for safety
authorprascle <prascle>
Fri, 20 May 2005 14:31:45 +0000 (14:31 +0000)
committerprascle <prascle>
Fri, 20 May 2005 14:31:45 +0000 (14:31 +0000)
src/Container/Component_i.cxx
src/Container/Container_i.cxx
src/Container/Container_init_python.cxx
src/Container/Container_init_python.hxx
src/Container/SALOME_Container.cxx
src/Container/SALOME_Container_i.hxx

index fb2dc2b68b56aeb9ea35e099b83d196776bea664..fd11e240bae2d7bac47aa708239a47c1515d5db6 100644 (file)
@@ -56,7 +56,8 @@ bool Engines_Component_i::_isMultiInstance = false;
 
 Engines_Component_i::Engines_Component_i()
 {
-  ASSERT(0);
+  //ASSERT(0);
+  INFOS("Default Constructor...");
 }
 
 //=============================================================================
index 76d135641558ae9246179632f8f675be7760e568..59671af749d6450151a954f0a0653acb70de96f0 100644 (file)
@@ -56,25 +56,6 @@ char ** _ArgV ;
 extern "C" {void ActSigIntHandler() ; }
 extern "C" {void SigIntHandler(int, siginfo_t *, void *) ; }
 
-
-// static PyMethodDef MethodPyVoidMethod[] = {{ NULL, NULL }};
-// PyThreadState *gtstate;
-
-// void init_python(int argc, char **argv)
-// {
-//   if (gtstate)
-//     return;
-//   Py_SetProgramName(argv[0]);
-//   Py_Initialize(); // Initialize the interpreter
-//   PySys_SetArgv(argc, argv);
-//   PyEval_InitThreads(); // Create (and acquire) the interpreter lock
-//   Py_InitModule( "InitPyRunMethod" , MethodPyVoidMethod ) ;
-//   //PyOS_setsig(SIGSEGV,&Handler);
-//   //PyOS_setsig(SIGINT,&Handler);
-//   gtstate = PyEval_SaveThread(); // Release the global thread state
-//   SCRUTE(gtstate);
-// }
-
 const char *Engines_Container_i::_defaultContainerName="FactoryServer";
 map<std::string, int> Engines_Container_i::_cntInstances_map;
 map<std::string, void *> Engines_Container_i::_library_map;
@@ -136,12 +117,15 @@ Engines_Container_i::Engines_Container_i (CORBA::ORB_ptr orb,
       MESSAGE("           argv" << i << " " << _argv[ i ]) ;
       i++ ;
     }
-  if ( argc != 4 )
+
+  if ( argc < 2 )
     {
-      MESSAGE("SALOME_Container usage : SALOME_Container ServerName " <<
-             "-ORBInitRef NameService=corbaname::hostname:tcpipPortNumber") ;
-      //    exit(0) ;
+      INFOS("SALOME_Container usage : SALOME_Container ServerName");
+      ASSERT(0) ;
     }
+  SCRUTE(argv[1]);
+  _isSupervContainer = false;
+  if (strcmp(argv[1],"SuperVisionContainer") == 0) _isSupervContainer = true;
 
   _containerName = BuildContainerNameForNS(containerName,hostname.c_str());
   
@@ -173,11 +157,13 @@ Engines_Container_i::Engines_Container_i (CORBA::ORB_ptr orb,
       myCommand += "')\n";
       SCRUTE(myCommand);
 
-      SCRUTE(KERNEL_PYTHON::_gtstate);
-      PyEval_RestoreThread(KERNEL_PYTHON::_gtstate);
-      PyRun_SimpleString("import SALOME_Container\n");
-      PyRun_SimpleString((char*)myCommand.c_str());
-      PyEval_ReleaseThread(KERNEL_PYTHON::_gtstate);
+      if (!_isSupervContainer)
+       {
+         Py_ACQUIRE_NEW_THREAD;
+         PyRun_SimpleString("import SALOME_Container\n");
+         PyRun_SimpleString((char*)myCommand.c_str());
+         Py_RELEASE_NEW_THREAD;
+       }
     }
 }
 
@@ -308,14 +294,18 @@ Engines_Container_i::load_component_Library(const char* componentName)
   // --- try import Python component
 
   INFOS("try import Python component "<<componentName);
+  if (_isSupervContainer)
+    {
+      INFOS('Supervision Container does not support Python Component Engines');
+      return false;
+    }
   if (_library_map[aCompName])
     {
       return true; // Python Component, already imported
     }
   else
     {
-      SCRUTE(KERNEL_PYTHON::_gtstate);
-      PyEval_RestoreThread(KERNEL_PYTHON::_gtstate);
+      Py_ACQUIRE_NEW_THREAD;
       PyObject *mainmod = PyImport_AddModule("__main__");
       PyObject *globals = PyModule_GetDict(mainmod);
       PyObject *pyCont = PyDict_GetItemString(globals, "pyCont");
@@ -324,7 +314,7 @@ Engines_Container_i::load_component_Library(const char* componentName)
                                             "s",componentName);
       int ret= PyInt_AsLong(result);
       SCRUTE(ret);
-      PyEval_ReleaseThread(KERNEL_PYTHON::_gtstate);
+      Py_RELEASE_NEW_THREAD;
   
       if (ret) // import possible: Python component
        {
@@ -363,6 +353,11 @@ Engines_Container_i::create_component_instance(const char*genericRegisterName,
   string aCompName = genericRegisterName;
   if (_library_map[aCompName]) // Python component
     {
+      if (_isSupervContainer)
+       {
+         INFOS('Supervision Container does not support Python Component Engines');
+         return Engines::Component::_nil();
+       }
       _numInstanceMutex.lock() ; // lock on the instance number
       _numInstance++ ;
       int numInstance = _numInstance ;
@@ -374,8 +369,7 @@ Engines_Container_i::create_component_instance(const char*genericRegisterName,
       string component_registerName =
        _containerName + "/" + instanceName;
 
-      SCRUTE(KERNEL_PYTHON::_gtstate);
-      PyEval_RestoreThread(KERNEL_PYTHON::_gtstate);
+      Py_ACQUIRE_NEW_THREAD;
       PyObject *mainmod = PyImport_AddModule("__main__");
       PyObject *globals = PyModule_GetDict(mainmod);
       PyObject *pyCont = PyDict_GetItemString(globals, "pyCont");
@@ -387,7 +381,7 @@ Engines_Container_i::create_component_instance(const char*genericRegisterName,
                                             studyId);
       string iors = PyString_AsString(result);
       SCRUTE(iors);
-      PyEval_ReleaseThread(KERNEL_PYTHON::_gtstate);
+      Py_RELEASE_NEW_THREAD;
   
       CORBA::Object_var obj = _orb->string_to_object(iors.c_str());
       iobject = Engines::Component::_narrow( obj ) ;
index 1aac1d05c2cd233ababccbe2d7ae0a0e7f388d96..7a4e585275ec41032421a6703d2b045ddd242362 100644 (file)
@@ -33,6 +33,7 @@ using namespace std;
 
 PyThreadState *KERNEL_PYTHON::_gtstate = 0;
 PyObject *KERNEL_PYTHON::salome_shared_modules_module = NULL;
+PyInterpreterState *KERNEL_PYTHON::_interp = NULL;
 
 void KERNEL_PYTHON::init_python(int argc, char **argv)
 {
@@ -48,6 +49,7 @@ void KERNEL_PYTHON::init_python(int argc, char **argv)
   Py_SetProgramName(argv[0]);
   Py_Initialize(); // Initialize the interpreter
   PySys_SetArgv(argc, argv);
+  KERNEL_PYTHON::_interp = PyThreadState_Get()->interp;
   PyEval_InitThreads(); // Create (and acquire) the interpreter lock
   ASSERT(!KERNEL_PYTHON::_gtstate);
   KERNEL_PYTHON::_gtstate = PyEval_SaveThread(); // Release global thread state
index c28e99cd5fce9ae52b39bdb49ff9baa396bc7766..acaef6307a1239778dddde5656b5dca16dbe41a8 100644 (file)
 #include <pthread.h>  // must be before Python.h !
 #include <Python.h>
 
+
+// next two MACRO must be used together only once inside a block
+// -------------------------------------------------------------
+// protect a sequence of Python calls:
+// - Python lock must be acquired for these calls
+// - new Python thread state allows multi thread use of the sequence:
+//    - Python may release the lock within the sequence, so multiple
+//      thread execution of the sequence may occur.
+//    - For that case, each sequence call must use a specific Python
+//      thread state.
+//    - There is no need of C Lock protection of the sequence.
+
+#define Py_ACQUIRE_NEW_THREAD \
+  PyEval_AcquireLock(); \
+  PyThreadState *myTstate = PyThreadState_New(KERNEL_PYTHON::_interp); \
+  PyThreadState *myoldTstate = PyThreadState_Swap(myTstate);
+
+#define Py_RELEASE_NEW_THREAD \
+  PyEval_ReleaseThread(myTstate); \
+  PyThreadState_Delete(myTstate);
+
 struct  KERNEL_PYTHON
 {
   static PyThreadState *_gtstate;
   static PyObject *salome_shared_modules_module;
+  static PyInterpreterState *_interp;
 
   static void init_python(int argc, char **argv);
 
index 174bc4a00219830b9f239ccc18809d9b260bcc41..f6bb9b0fe8de9f11d756cb9c0372a041941a53a0 100644 (file)
@@ -59,16 +59,28 @@ int main(int argc, char* argv[])
   MPI_Init(&argc,&argv);
 #endif
   // Initialise the ORB.
-  //ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance() ;
   CORBA::ORB_var orb = CORBA::ORB_init( argc , argv ) ;
   SALOMETraceCollector *myThreadTrace = SALOMETraceCollector::instance(orb);
   INFOS_COMPILATION;
   BEGIN_OF(argv[0]);
 
-  int _argc = 1;
-  char* _argv[] = {""};
-  KERNEL_PYTHON::init_python(_argc,_argv);
+  ASSERT(argc > 1);
+  SCRUTE(argv[1]);
+  bool isSupervContainer = false;
+  if (strcmp(argv[1],"SuperVisionContainer") == 0) isSupervContainer = true;
+
+  if (!isSupervContainer)
+    {
+      int _argc = 1;
+      char* _argv[] = {""};
+      KERNEL_PYTHON::init_python(argc,argv);
+    }
+  else
+    {
+      Py_Initialize() ;
+      PySys_SetArgv( argc , argv ) ;
+    }
+
   try{
     // Obtain a reference to the root POA.
     // obtain the root poa manager
index a3840cfb615f83c6280ae1b89f432c02260f998d..06e1f1aa88f28e50a455f20f6fc3a6d09f9f0d74 100644 (file)
@@ -112,6 +112,8 @@ protected:
   static std::map<std::string, void *> _toRemove_map;// library names to remove
   static omni_mutex _numInstanceMutex ; // lib and instance protection
 
+  bool _isSupervContainer;
+
   SALOME_NamingService *_NS ;
   std::string _library_path;
   std::string _containerName;