]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
Fix on crashes on parallel execution of python scripts from different frames and...
authorsmh <smh@opencascade.com>
Wed, 28 Apr 2004 08:51:25 +0000 (08:51 +0000)
committersmh <smh@opencascade.com>
Wed, 28 Apr 2004 08:51:25 +0000 (08:51 +0000)
12 files changed:
src/SALOMEGUI/PyInterp_PyQt.cxx
src/SALOMEGUI/PyInterp_PyQt.h
src/SALOMEGUI/PyInterp_base.cxx
src/SALOMEGUI/PyInterp_base.h
src/SALOMEGUI/QAD_PyEditor.cxx
src/SALOMEGUI/QAD_PyInterp.cxx
src/SALOMEGUI/QAD_PyInterp_mono.cxx
src/SALOMEGUI/QAD_RightFrame.cxx
src/SALOMEGUI/QAD_RightFrame.h
src/SALOMEGUI/QAD_Study.cxx
src/SALOMEGUI/QAD_StudyFrame.cxx
src/SALOMEGUI/QAD_StudyFrame.h

index ecd145c4b035953ebb43b2c453b201da81d83f44..ae688800fa990afdd0974c6ceebbcf5cc1dc951c 100644 (file)
@@ -9,13 +9,11 @@
 //  Module : SALOME
 //  $Header$
 
-using namespace std;
-using namespace std;
 #include "PyInterp_PyQt.h"
-
 #include "utilities.h"
 
-extern "C" PyObject * PyEval_EvalCode(PyObject *co, PyObject *g, PyObject *l);
+using namespace std;
+
 
 /*!
  * constructor : the main SALOME Python interpreter is used for PyQt GUI.
@@ -33,7 +31,6 @@ PyInterp_PyQt::~PyInterp_PyQt()
 
 void PyInterp_PyQt::initState()
 {
-  salomeAcquireLock();           //acquire python global lock (one for all interpreters)
   SCRUTE(PyInterp_base::_gtstate);
   _tstate=PyInterp_base::_gtstate;
   PyThreadState_Swap(_tstate);
@@ -48,49 +45,23 @@ void PyInterp_PyQt::initContext()
   Py_DECREF(bimod);
 }
 
-void PyInterp_PyQt::enter()
-{
-  PyThreadState *oldstate;
-  SCRUTE(_tstate);
-  salomeAcquireLock();
-  oldstate=PyThreadState_Swap(_tstate);
-  SCRUTE(oldstate);
-}
-
-void PyInterp_PyQt::quit()
-{
-  MESSAGE("quit");
-  salomeReleaseLock();
-  MESSAGE("fin quit");
-}
-
 void PyInterp_PyQt::run(const char *command)
 {
-  PyObject *code,*r;
-  enter();
   MESSAGE("compile");
-  code=Py_CompileString((char *)command,"PyGUI",Py_file_input);
-  if (code == NULL)
-    {
-      /*
-       Une erreur s est produite en general SyntaxError
-      */
-      PyErr_Print();
-      quit();
-      return;
-    }
-  r  = PyEval_EvalCode(code,_g,_g);
+  PyLockWrapper aLock(_tstate);
+  PyObject *code = Py_CompileString((char *)command,"PyGUI",Py_file_input);
+  if(!code){
+    // Une erreur s est produite en general SyntaxError
+    PyErr_Print();
+    return;
+  }
+  PyObject *r = PyEval_EvalCode(code,_g,_g);
   Py_DECREF(code);
-  if (r==NULL)
-    {
-      /*
-       Une erreur s est produite a l execution
-      */
-      PyErr_Print();
-      quit();
-      return;
-    }
+  if(!r){
+    // Une erreur s est produite a l execution
+    PyErr_Print();
+    return;
+  }
   Py_DECREF(r);
-  quit();
 }
 
index bc6a29849da2e0a20ee6fbe3a0c1e9992c1c79d1..74d743e279fa58068d17f9bcc50d0a7493ab228f 100644 (file)
@@ -19,13 +19,12 @@ class PyInterp_PyQt : public PyInterp_base
  public:
   PyInterp_PyQt();
   ~PyInterp_PyQt();
-  void enter();
-  void quit();
+
   void run(const char *command);
 
  protected:
-  void initState();
-  void initContext();  
+  virtual void initState();
+  virtual void initContext();  
 };
 
 #endif
index f9d03e760673cebd5b6486735449b8543b28a1f8..ec972ff71d7e567dc69f5da988bf82cc4ad12174 100644 (file)
 //  Module : SALOME
 //  $Header$
 
-using namespace std;
-#include "PyInterp_base.h"
-#include "utilities.h"
 #include <string>
 #include <vector>
+
+#include <Python.h>
 #include <cStringIO.h>
 
+#include <qmutex.h>
+
+#include "PyInterp_base.h"
+#include "utilities.h"
+
+
 using namespace std;
 
-extern "C" PyObject * PyEval_EvalCode(PyObject *co, PyObject *g, PyObject *l);
 
-static PyThreadState *savedThreadState = NULL;
+#ifdef _DEBUG_
+static int MYDEBUG = 1;
+#else
+static int MYDEBUG = 0;
+#endif
 
-/*!
- * We have our own routines which are identical to the SIP routines
- * to not depend from SIP software evolutions
- */
+static QMutex myMutex;
 
-extern "C" void salomeAcquireLock()
+PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState): 
+  myThreadState(theThreadState),
+  mySaveThreadState(PyInterp_base::_gtstate)
 {
-  MESSAGE("salomeAcquireLock");
-  PyEval_RestoreThread(savedThreadState);
-  savedThreadState = NULL;
-}
+  if(MYDEBUG) MESSAGE(" PyLockWrapper(...) - myThreadState = "<<myThreadState<<" - "<<myMutex.locked());
+  myMutex.lock();
+  PyEval_RestoreThread(myThreadState);
 
-extern "C" void salomeReleaseLock()
-{
-  MESSAGE("salomeReleaseLock");
-  savedThreadState = PyEval_SaveThread();
-}
+  //PyEval_AcquireLock();
+  //PyThreadState_Swap(myThreadState);
 
-extern "C" int salomeCondAcquireLock()
-{
-  MESSAGE("salomeCondAcquireLock");
-  if(savedThreadState != NULL)
-    {
-      /*
-       * If savedThreadState is not NULL, Python global lock is not already acquired
-       * We acquire it
-       * and return 1 to the caller
-       */
-      salomeAcquireLock();
-      //MESSAGE("We got it (the lock)");
-      return 1;
-    }
-  /*
-   * If savedThreadState is NULL, Python global lock is already acquired
-   * We don't acquire or release it
-   * We return 0 to the caller
-   * CAUTION : it's only true when there is no event programming running (Tkinter, PyQt)
-   */
-  return 0;
-}
+  //PyEval_SaveThread();
 
-extern "C" void salomeCondReleaseLock(int rellock)
-{
-  MESSAGE("salomeCondReleaseLock");
-  if(rellock )
-    salomeReleaseLock();
+  //mySaveThreadState = PyThreadState_Swap(myThreadState);
+  //PyEval_ReleaseLock();
 }
 
-// main python interpreter
 
-PyThreadState *PyInterp_base::_gtstate=0; // force 0 before execution
-int PyInterp_base::_argc=1;
-char* PyInterp_base::_argv[] = {""};
+PyLockWrapper::~PyLockWrapper(){
+  if(MYDEBUG) MESSAGE("~PyLockWrapper(...) - myThreadState = "<<myThreadState);
+  PyEval_SaveThread();
+  myMutex.unlock();
 
-PyObject *PyInterp_base::builtinmodule=NULL;
-PyObject *PyInterp_base::salome_shared_modules_module=NULL;
+  //PyThreadState_Swap(NULL);
+  //PyEval_ReleaseLock();
 
-void init_python()
-{
-  SCRUTE(PyInterp_base::_gtstate);
-  if (PyInterp_base::_gtstate) return;
-  Py_Initialize();               // Initialize the interpreter
-  PyEval_InitThreads();          // Create (and acquire) the interpreter lock
-  PySys_SetArgv(PyInterp_base::_argc,PyInterp_base::_argv);      // initialize sys.argv
-  PyInterp_base::_gtstate = PyThreadState_Get();
-  SCRUTE(PyInterp_base::_gtstate);
+  //PyEval_RestoreThread(myThreadState);
 
-  //   /*
-  //    * Import __builtin__ module and store it to use it with all sub-interpreters
-  //    * This hack could be used with event programming (PyQt) to avoid errors 
-  //    * encountered with incoherent builtins
-  //    */
+  //PyEval_AcquireLock();
+  //PyThreadState_Swap(mySaveThreadState);
+}
 
-  //   PyInterp_base::builtinmodule =PyImport_ImportModule("__builtin__");
-  //   SCRUTE(PyInterp_base::builtinmodule->ob_refcnt);
 
-  /*
-   * Import salome_shared_modules module and store it to use it with all sub-interpreters
-   */
+class PyReleaseLock{
+public:
+  ~PyReleaseLock(){
+    if(MYDEBUG) MESSAGE("~PyReleaseLock()");
+    //PyEval_SaveThread();
 
-  PyInterp_base::salome_shared_modules_module =PyImport_ImportModule("salome_shared_modules");
-  if(PyInterp_base::salome_shared_modules_module == NULL){
-      MESSAGE("init_python: problem with salome_shared_modules import");
-      PyErr_Print();
-      PyErr_Clear();
-      salomeReleaseLock();
-      return;
+    PyEval_ReleaseLock();
   }
-  SCRUTE(PyInterp_base::salome_shared_modules_module->ob_refcnt);
-  salomeReleaseLock();
+};
+
+
+PyLockWrapper PyInterp_base::GetLockWrapper(){
+  return PyLockWrapper(_tstate);
 }
 
+// main python interpreter
+
+PyThreadState *PyInterp_base::_gtstate = 0; // force 0 before execution
+int PyInterp_base::_argc = 1;
+char* PyInterp_base::_argv[] = {""};
+
+PyObject *PyInterp_base::builtinmodule = NULL;
+PyObject *PyInterp_base::salome_shared_modules_module = NULL;
+
 /*!
  * This function compiles a string (command) and then evaluates it in the dictionnary
  * context if possible.
@@ -122,74 +97,44 @@ void init_python()
  *  1 : incomplete text
  *  0 : complete text executed with success
  */
-
 int compile_command(const char *command,PyObject *context)
 {
-  SCRUTE(command);
-  PyObject *m,*v,*r;
-
-  m=PyImport_AddModule("codeop");
-  if(m == NULL)
-    {
-      /*
-       * Fatal error. No way to go on.
-       */
+  PyObject *m = PyImport_AddModule("codeop");
+  if(!m){ // Fatal error. No way to go on.
+    PyErr_Print();
+    return -1;
+  }
+  PyObjWrapper v(PyObject_CallMethod(m,"compile_command","s",command));
+  if(!v){
+    // Error encountered. It should be SyntaxError,
+    //so we don't write out traceback
+    PyObjWrapper exception, value, tb;
+    PyErr_Fetch(&exception, &value, &tb);
+    PyErr_NormalizeException(&exception, &value, &tb);
+    PyErr_Display(exception, value, NULL);
+    return -1;
+  }else if (v == Py_None){
+    // Incomplete text we return 1 : we need a complete text to execute
+    return 1;
+  }else{
+    // Complete and correct text. We evaluate it.
+    PyObjWrapper r(PyEval_EvalCode(v,context,context));
+    if(!r){
+      // Execution error. We return -1
       PyErr_Print();
       return -1;
     }
-  v= PyObject_CallMethod(m,"compile_command","s",command);
-  if (v == NULL)
-    {
-      /*
-       * Error encountered. It should be SyntaxError
-       * so we don't write out traceback
-       */
-      PyObject *exception,*value,*tb;
-      PyErr_Fetch(&exception, &value, &tb);
-      PyErr_NormalizeException(&exception, &value, &tb);
-      PyErr_Display(exception, value, NULL);
-      Py_XDECREF(exception);
-      Py_XDECREF(value);
-      Py_XDECREF(tb);
-
-      return -1;
-    }
-  else if (v == Py_None)
-    {
-      /*
-       *  Incomplete text we return 1 : we need a complete text to execute
-       */
-      return 1;
-    }
-  else
-    {
-      /*
-       * Complete and correct text. We evaluate it.
-       */
-      r  = PyEval_EvalCode(v,context,context);
-      Py_DECREF(v);
-      if (r==NULL)
-       {
-         /*
-          * Execution error. We return -1
-          */
-         PyErr_Print();
-         return -1;
-       }
-      Py_DECREF(r);
-      /*
-       * The command has been successfully executed. Return 0
-       */
-      return 0;
-    }
+    // The command has been successfully executed. Return 0
+    return 0;
+  }
 }
 
+
 /*!
  * basic constructor here : herited classes constructors must call initalize() method
  * defined here.
  */
-
-PyInterp_base::PyInterp_base():_tstate(0),_vout(0),_verr(0),_g(0),_atFirst(true)
+PyInterp_base::PyInterp_base(): _tstate(0), _vout(0), _verr(0), _g(0), _atFirst(true)
 {
   MESSAGE("PyInterp_base::PyInterp_base()");
 }
@@ -197,12 +142,35 @@ PyInterp_base::PyInterp_base():_tstate(0),_vout(0),_verr(0),_g(0),_atFirst(true)
 PyInterp_base::~PyInterp_base()
 {
   MESSAGE("PyInterp_base::~PyInterp_base()");
-  salomeAcquireLock();
+  PyLockWrapper aLock(_tstate);
   PyThreadState_Swap(_tstate);
   Py_EndInterpreter(_tstate);
-  salomeReleaseLock();
 }
 
+
+void init_python()
+{
+  if(MYDEBUG) MESSAGE("init_python()"); 
+  if (PyInterp_base::_gtstate) return;
+  Py_Initialize(); // Initialize the interpreter
+
+  PyEval_InitThreads(); // Initialize and acquire the global interpreter lock
+
+  PySys_SetArgv(PyInterp_base::_argc,PyInterp_base::_argv); // initialize sys.argv
+  PyInterp_base::_gtstate = PyThreadState_Get();
+  if(MYDEBUG) SCRUTE(PyInterp_base::_gtstate);
+
+  PyInterp_base::salome_shared_modules_module = PyImport_ImportModule("salome_shared_modules");
+  if(!PyInterp_base::salome_shared_modules_module){
+    MESSAGE("init_python: problem with salome_shared_modules import");
+    PyErr_Print();
+    PyErr_Clear();
+  }else{
+    if(MYDEBUG) SCRUTE(PyInterp_base::salome_shared_modules_module->ob_refcnt);
+  }
+}
+
+
 /*!
  * Must be called by herited classes constructors. initialize() calls virtuals methods
  * initstate & initcontext, not defined here in base class. initstate & initcontext methods
@@ -211,233 +179,143 @@ PyInterp_base::~PyInterp_base()
  */
 void PyInterp_base::initialize()
 {
-  MESSAGE("PyInterp_base::initialize()");
-  PyObject *m,*v,*c;
-
+  if(MYDEBUG) MESSAGE("PyInterp_base::initialize()");
   _history.clear();       // start a new list of user's commands 
   _ith = _history.begin();
 
+  PyReleaseLock aReleaseLock;
   init_python();
 
+  //PyLockWrapper aLock(_tstate);
   initState();
-
   initContext();
 
-  m=PyImport_ImportModule("codeop"); // used to interpret & compile commands
-  if(m == NULL)
-    {
-      MESSAGE("Problem...");
-      PyErr_Print();
-      ASSERT(0);
-      salomeReleaseLock(); 
-      return;
-    }   
-  Py_DECREF(m);   
+  // used to interpret & compile commands
+  PyObjWrapper m(PyImport_ImportModule("codeop"));
+  if(!m){
+    if(MYDEBUG)  MESSAGE("Problem...");
+    PyErr_Print();
+    ASSERT(0);
+    return;
+  }   
   
-  /*
-   *  Create cStringIO to capture stdout and stderr
-   */
+  // Create cStringIO to capture stdout and stderr
   //PycString_IMPORT;
-  PycStringIO=(PycStringIO_CAPI *)xxxPyCObject_Import("cStringIO", "cStringIO_CAPI");
-  _vout=PycStringIO->NewOutput(128);
-  _verr=PycStringIO->NewOutput(128);
+  PycStringIO = (PycStringIO_CAPI *)xxxPyCObject_Import("cStringIO", "cStringIO_CAPI");
+  _vout = PycStringIO->NewOutput(128);
+  _verr = PycStringIO->NewOutput(128);
   
   // All the initRun outputs are redirected to the standard output (console)
-  this->initRun();
+  initRun();
 
   // We go out of Python world to enter the C++ world. Release the Python global lock 
-  salomeReleaseLock();
-  SCRUTE(_tstate);
-  SCRUTE(this);
+  if(MYDEBUG) SCRUTE(_tstate);
 }
 
 string PyInterp_base::getbanner()
 {
-  MESSAGE("PyInterp_base::getbanner()");
-  string banner = "Python ";
-  banner = banner + Py_GetVersion() + " on " + Py_GetPlatform() ;
-  banner = banner + "\ntype help to get general information on environment\n";
-  return banner.c_str();
+  string aBanner("Python ");
+  aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
+  aBanner = aBanner + "\ntype help to get general information on environment\n";
+  return aBanner;
 }
 
+
 int PyInterp_base::initRun()
 {
-  MESSAGE("PyInterp_base::initRun()");
+  if(MYDEBUG) MESSAGE("PyInterp_base::initRun()");
   PySys_SetObject("stderr",_verr);
   PySys_SetObject("stdout",_vout);
 
-  PyObject *v = PyObject_CallMethod(_verr,"reset","");
-  Py_XDECREF(v);
-  v = PyObject_CallMethod(_vout,"reset","");
-  Py_XDECREF(v);
+  PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
+  PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
 
-
-  PyObject *m;
-  m = PyImport_GetModuleDict();
+  PyObject *m = PyImport_GetModuleDict();
   
   PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
   PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
 
-  MESSAGE(this->getvout());
-  MESSAGE(this->getverr());
-    
   return 0;
 }
 
-void PyInterp_base::enter()
-{
-  MESSAGE("PyInterp_base::enter()");
-  salomeAcquireLock();
-  PyThreadState_Swap(_tstate);
-}
-
-void PyInterp_base::quit()
-{
-  MESSAGE("PyInterp_base::quit()");
-  salomeReleaseLock();
-}
-
-void PyInterp_base::basicRun(const char *command)
-{
-  SCRUTE(command);
-  PyObject *code,*r;
-  enter();
-  code=Py_CompileString((char *)command,"PyInterp_base",Py_file_input);
-  if (code == NULL)
-    {
-      /*
-       * Caught an error : SyntaxError
-       * Print it and quit
-       */
-      PyErr_Print();
-      quit();
-      return;
-    }
-  r = PyEval_EvalCode(code,_g,_g);
-  Py_DECREF(code);
-  if (r==NULL)
-    {
-      /*
-       * Caught an error during execution
-       * Print it and quit
-       */
-      PyErr_Print();
-      quit();
-      return;
-    }
-  Py_DECREF(r);
-  quit();
-}
 
 int PyInterp_base::run(const char *command)
 {
-  SCRUTE(command);
-  int ret = 0;
-  if (_atFirst)
-    {
-      _atFirst = false;
-      ret = this->simpleRun("from Help import *");
-      MESSAGE(this->getvout())
-       MESSAGE(this->getverr())
-       if (ret != 0) return ret;
-      ret = this->simpleRun("import salome");
-      MESSAGE(this->getvout());
-      MESSAGE(this->getverr())
-       if (ret != 0) return ret;
-    }
-  ret = this->simpleRun(command);
-  return ret;
+  if(_atFirst){
+    int ret = 0;
+    _atFirst = false;
+    ret = simpleRun("from Help import *");
+    if (ret) return ret;
+    ret = simpleRun("import salome");
+    if (ret) return ret;
+  }
+  return simpleRun(command);
 }
 
+
 int PyInterp_base::simpleRun(const char *command)
 {
-  SCRUTE(command);
-  PyObject *v,*m,*r,*g;
-  char *output;
-  int ier=0;
-  string s_com = command;
-
-  if (s_com.size() > 0)
-    {
-      _history.push_back(s_com);
-      _ith = _history.end();
-      SCRUTE(_history.back());
-    }
+  if(MYDEBUG) MESSAGE("simpleRun(...) - command = '"<<command<<"'"); 
+  if(strcmp(command,"") != 0){
+    _history.push_back(command);
+    _ith = _history.end();
+  }
 
-  //   SCRUTE(this);
-  //   SCRUTE(_tstate);
   // We come from C++ to enter Python world
   // We need to acquire the Python global lock
-  salomeAcquireLock();
-  // Restore the sub interpreter thread state : this._tstate
-  PyThreadState_Swap(_tstate);
+  PyLockWrapper aLock(_tstate);
 
-  /*
-    Reset redirected outputs before treatment
-  */
+  // Reset redirected outputs before treatment
   PySys_SetObject("stderr",_verr);
   PySys_SetObject("stdout",_vout);
-
-  v = PyObject_CallMethod(_verr,"reset","");
-  Py_XDECREF(v);
-  v = PyObject_CallMethod(_vout,"reset","");
-  Py_XDECREF(v);
+    
+  PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
+  PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
   
-  ier=compile_command(command,_g);
+  int ier = compile_command(command,_g);
 
   // Outputs are redirected on standards outputs (console)
   PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
   PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
-
-  // We go back to the C++ world. Release the lock.
-  salomeReleaseLock();
   return ier;
 }
 
-static string vout_buffer;
-static string verr_buffer;
-
-char * PyInterp_base::getverr()
-{ 
-  MESSAGE("PyInterp_base::getverr"); 
-  PyObject *v;
-  v=PycStringIO->cgetvalue(_verr);
-  verr_buffer=PyString_AsString(v);
-  Py_DECREF(v);
-  return (char *)verr_buffer.c_str();
-}
 
-char * PyInterp_base::getvout()
-{  
-  MESSAGE("PyInterp_base::getvout"); 
-  PyObject *v;
-  v=PycStringIO->cgetvalue(_vout);
-  vout_buffer=PyString_AsString(v);
-  Py_DECREF(v);
-  return (char *)vout_buffer.c_str();
-}
 const char * PyInterp_base::getPrevious()
 {
-  MESSAGE("PyInterp_base::getPrevious"); 
-  if (_ith != _history.begin())
-    {
-      _ith--;
-      return (*_ith).c_str();
-    }
+  if(_ith != _history.begin()){
+    _ith--;
+    return (*_ith).c_str();
+  }
   else
     return BEGIN_HISTORY_PY;
 }
 
+
 const char * PyInterp_base::getNext()
 {
-  MESSAGE("PyInterp_base::getNext"); 
-  if (_ith != _history.end())
-    {
-      _ith++;
-    }
+  if(_ith != _history.end()){
+    _ith++;
+  }
   if (_ith == _history.end())
     return TOP_HISTORY_PY;
   else
     return (*_ith).c_str();
 }
+
+
+string PyInterp_base::getverr(){ 
+  //PyLockWrapper aLock(_tstate);
+  PyObjWrapper v(PycStringIO->cgetvalue(_verr));
+  string aRet(PyString_AsString(v));
+  return aRet;
+}
+
+
+string PyInterp_base::getvout(){  
+  //PyLockWrapper aLock(_tstate);
+  PyObjWrapper v(PycStringIO->cgetvalue(_vout));
+  string aRet(PyString_AsString(v));
+  return aRet;
+}
index 1e4ac5fea7d0fb9d48e5d6c4983bd221e98ad342..216b1e596ac0847da1b678257f98fda89af8c905 100644 (file)
 #ifndef _PYINTERP_BASE_H_
 #define _PYINTERP_BASE_H_
 
-#include <iostream>
-#include <Python.h>
 #include <list>
 #include <string>
+#include <iostream>
+
+#include <Python.h>
 
-using namespace std;
+extern "C" PyObject * PyEval_EvalCode(PyObject *co, PyObject *g, PyObject *l);
 
 #define TOP_HISTORY_PY "--- top of history ---"
 #define BEGIN_HISTORY_PY "--- begin of history ---"
 
-/*!
- * We have our own routines which are identical to the SIP routines
- * to not depend from SIP software evolutions
- */
 
-extern "C" void salomeAcquireLock();
-extern "C" void salomeReleaseLock();
-extern "C" int salomeCondAcquireLock();
-extern "C" void salomeCondReleaseLock(int rellock);
+class PyLockWrapper{
+  PyThreadState* myThreadState;
+  PyThreadState* mySaveThreadState;
+ public:
+  PyLockWrapper(PyThreadState* theThreadState);
+  ~PyLockWrapper();
+};
 
-/*! this class can only be used with derivation : 
- *  2 pure virtual methods, initstate() & initcontext()
- */
 
-class PyInterp_base
-{
+class PyInterp_base{
  public:
   static PyThreadState *_gtstate;
   static int _argc;
   static char* _argv[];
   static PyObject *builtinmodule;
   static PyObject *salome_shared_modules_module;
-
+  
   PyInterp_base();
   ~PyInterp_base();
-  void initialize();
+  
+  virtual void initialize();
+
   int run(const char *command); 
-  char * getverr();
-  char * getvout();  
-  string getbanner(); 
+
+  PyLockWrapper GetLockWrapper();
+
+  std::string getbanner(); 
+  std::string getverr();
+  std::string getvout();  
+
   const char * getPrevious();
   const char * getNext();    
-  void enter();
-  void quit();
-  void basicRun(const char *command);
 
  protected:
   PyThreadState * _tstate;
-  PyObject      * _vout;
-  PyObject      * _verr;
-  PyObject      * _g;
-  list <string> _history;
-  list <string>::iterator _ith;
+  PyObject * _vout;
+  PyObject * _verr;
+  PyObject * _g;
+  std::list<std::string> _history;
+  std::list<std::string>::iterator _ith;
   bool _atFirst;
 
   int simpleRun(const char* command);
   int initRun();
 
   virtual void initState() = 0;
-  virtual void initContext() =0;  
+  virtual void initContext() = 0;  
 };
 
+
+class PyObjWrapper{
+  PyObject* myObject;
+public:
+  PyObjWrapper(PyObject* theObject): myObject(theObject) {}
+  PyObjWrapper(): myObject(0) {}
+  operator PyObject*(){
+    return myObject;
+  }
+  PyObject* operator->(){
+    return myObject;
+  }
+  PyObject* get(){
+    return myObject;
+  }
+  bool operator!(){
+    return !myObject;
+  }
+  bool operator==(PyObject* theObject){
+    return myObject == theObject;
+  }
+  PyObject** operator&(){
+    return &myObject;
+  }
+  PyObjWrapper& operator=(PyObjWrapper* theObjWrapper){
+    Py_XDECREF(myObject);
+    myObject = theObjWrapper->myObject;
+    return *this;
+  }
+  virtual ~PyObjWrapper(){ 
+    Py_XDECREF(myObject);
+  }
+};
+
+
 #endif
index 8c4744d280397caaf769763338f612f51686937d..8d0ae9fc5383ebfa9f5e7b04d102e8aff42e54bd 100644 (file)
@@ -103,7 +103,7 @@ QAD_PyEditor::QAD_PyEditor(QAD_PyInterp* interp,
   _currentPrompt = ">>> ";
   // put error messages of interpreter if they exist.
   _buf.truncate(0);
-  setText(_interp->getverr());
+  setText(_interp->getverr().c_str());
   setText(_currentPrompt);
   setPalette( QAD_Application::getPalette(true) );
   setWordWrap(NoWrap);
@@ -444,8 +444,8 @@ void QAD_PyEditor::customEvent(QCustomEvent *e)
   case PYTHON_ERROR:
     {
       _buf.truncate(0);
-      setText(_interp->getvout());
-      setText(_interp->getverr());
+      setText(_interp->getvout().c_str());
+      setText(_interp->getverr().c_str());
       _currentPrompt = ">>> ";
       setText(_currentPrompt);
       break;
index 5f04d820f6e5f352c15db968f9a4a8a0684f2594..94fed0921a515e66a0d40ad18e94529192ebcd53 100644 (file)
@@ -38,7 +38,6 @@ using namespace std;
  */
 QAD_PyInterp::QAD_PyInterp(): PyInterp_base()
 {
-  initialize();
 }
 
 QAD_PyInterp::~QAD_PyInterp()
@@ -66,70 +65,58 @@ QAD_PyInterp::~QAD_PyInterp()
 void QAD_PyInterp::initState()
 {
   MESSAGE("QAD_PyInterp::initState");
-  salomeAcquireLock();           //acquire python global lock (one for all interpreters)
-  _tstate = Py_NewInterpreter(); //create an interpreter and save current state
-  SCRUTE(_tstate);
-  SCRUTE(PyInterp_base::_argc);
-  SCRUTE(PyInterp_base::_argv[0]);
-  PySys_SetArgv(PyInterp_base::_argc,PyInterp_base::_argv);    // initialize sys.argv
+  _tstate = Py_NewInterpreter(); // create an interpreter and save current state
+  PySys_SetArgv(PyInterp_base::_argc,PyInterp_base::_argv); // initialize sys.argv
 
-  if(builtinmodule == NULL)return;
+  if(!builtinmodule) 
+    return;
   /*
    * If builtinmodule has been initialized all the sub interpreters
    * will have the same __builtin__ module
    */
-  PyObject *m=PyImport_GetModuleDict();
+  PyObject *m = PyImport_GetModuleDict();
   PyDict_SetItemString(m, "__builtin__", builtinmodule);
-  SCRUTE(builtinmodule->ob_refcnt);                            // builtinmodule reference counter
+  SCRUTE(builtinmodule->ob_refcnt); // builtinmodule reference counter
   _tstate->interp->builtins = PyModule_GetDict(builtinmodule);
   Py_INCREF(_tstate->interp->builtins);
 }
 
+
 void QAD_PyInterp::initContext()
 {
   MESSAGE("QAD_PyInterp::initContext");
-  PyObject *m;
-  m=PyImport_AddModule("__main__");  // interpreter main module (module context)
-  if(m == NULL)
-    {
-      MESSAGE("problem...");
-      PyErr_Print();
-      ASSERT(0);
-      salomeReleaseLock(); 
-      return;
-    }  
+  PyObject *m = PyImport_AddModule("__main__");  // interpreter main module (module context)
+  if(!m){
+    MESSAGE("problem...");
+    PyErr_Print();
+    ASSERT(0);
+    return;
+  }  
   _g = PyModule_GetDict(m);          // get interpreter dictionnary context
   SCRUTE(_g);
 
-  if(builtinmodule)
-    {
-      PyDict_SetItemString(_g, "__builtins__", builtinmodule); // assign singleton __builtin__ module
-    }
-// Debut modif CCAR
-  /*
-   * Import special module to change the import mechanism
-   */
-  m =PyImport_ImportModule("import_hook");
-  if(m == NULL){
-      MESSAGE("initContext: problem with import_hook import");
+  if(builtinmodule){
+    PyDict_SetItemString(_g, "__builtins__", builtinmodule); // assign singleton __builtin__ module
+  }
+
+  // Debut modif CCAR
+  // Import special module to change the import mechanism
+  PyObjWrapper m1(PyImport_ImportModule("import_hook"));
+  if(!m1){
+    MESSAGE("initContext: problem with import_hook import");
+    PyErr_Print();
+    PyErr_Clear();
+    ASSERT(0);
+  }else{
+    // Call init_shared_modules to initialize the shared import mechanism for modules 
+    //that must not be imported twice
+    PyObjWrapper m2(PyObject_CallMethod(m1,"init_shared_modules","O",salome_shared_modules_module));
+    if(!m2){
+      MESSAGE("initContext: problem with init_shared_modules call");
       PyErr_Print();
       PyErr_Clear();
       ASSERT(0);
+    }
   }
-  /*
-   * Call init_shared_modules to initialize the shared import mechanism for modules 
-   * that must not be imported twice
-   */
-  if(m != NULL){
-      m= PyObject_CallMethod(m,
-                        "init_shared_modules","O",salome_shared_modules_module);
-      if (m == NULL){
-          MESSAGE("initContext: problem with init_shared_modules call");
-          PyErr_Print();
-          PyErr_Clear();
-          ASSERT(0);
-      }
-  }
-// Fin   modif CCAR
-
+  // Fin   modif CCAR
 }
index e1be19054f92ba2205469feca27772826fa0a78e..9c3ab30c908fe4ae79de1a36488ae04d3ac9224c 100644 (file)
@@ -9,11 +9,12 @@
 //  Module : SALOME
 //  $Header$
 
-using namespace std;
-using namespace std;
+
 #include "QAD_PyInterp_mono.h"
 #include "utilities.h"
 
+using namespace std;
+
 /*!
  * constructor : only one Python interpreter, shared within SALOME studies.
  * calls initialize method defined in base class, which calls virtual methods
@@ -38,7 +39,6 @@ QAD_PyInterp_mono::~QAD_PyInterp_mono()
 
 void QAD_PyInterp_mono::initState()
 {
-  salomeAcquireLock(); //acquire python global lock (one for all interpreters)
   _tstate = PyThreadState_Get();
   PySys_SetArgv(PyInterp_base::_argc,PyInterp_base::_argv);      // initialize sys.argv
 }
index 806a1503cf4a380319d3f93778e02d00c450a320..4ccd5d679131c54b03869cb36cfef16f8c20f691 100644 (file)
 //  Module : SALOME
 //  $Header$
 
-using namespace std;
 #include "QAD_RightFrame.h"
 #include "QAD_Application.h"
 #include "QAD_Desktop.h"
 #include "QAD_StudyFrame.h"
 #include "QAD_Tools.h"
+#include "QAD_PyInterp.h"
+
 #include <qvaluelist.h>
 
 // QT Include
@@ -40,6 +41,8 @@ using namespace std;
 // Open CASCADE Include
 #include <OSD_SharedLibrary.hxx>
 
+using namespace std;
+
 /*!
   \class QAD_RightFrame QAD_RightFrame.h
   \brief Frame window which contains QAD_ViewFrame, QAD_PyInterp and QAD_Message.
index 1b454310aa6dbd4486e7e28b398a32f1b7962903..e28a9e43085cf092528ebcc9df3751c3f6706825 100644 (file)
@@ -33,7 +33,8 @@
 #include "QAD_Message.h"
 #include "QAD_PyEditor.h"
 #include "QAD_Splitter.h"
-#include "QAD_PyInterp.h"
+
+class QAD_PyInterp;
 
 class QAD_EXPORT QAD_RightFrame : public QAD_Splitter
 {
index 1be9aef0e0b111f80415207363ee22c0fd2162c1..64939d0d14c9a95d9cede355be5dcdbdfc264ca3 100644 (file)
@@ -91,6 +91,7 @@ myPath( path )
     /* create python interpreter */
     _interp = new QAD_PyInterp();
     SCRUTE(_interp);
+    _interp->initialize();
 
     /* create default selection */
     //NRI    Selection( "Salome" );
index 29bde65b10062d15e3721e005fca7be8d592ff96..8e65a6ae5c42bef56004cd0005f666a2e7f54df5 100644 (file)
@@ -26,7 +26,6 @@
 //  Module : SALOME
 //  $Header$
 
-using namespace std;
 /*!
   \class QAD_StudyFrame QAD_StudyFrame.h
   \brief Frame window which contains QAD_LeftFrame and QAD_RightFrame.
@@ -39,8 +38,11 @@ using namespace std;
 #include "QAD_Desktop.h"
 #include "QAD_Study.h"
 #include "QAD_ObjectBrowser.h"
+#include "QAD_PyInterp.h"
 #include <qvaluelist.h>
 
+using namespace std;
+
 /*!
     Constructor
 */
index e8b393b441a938b7d036f4d611301433ab224f99..5727e13c06483cce6b7520b10dd5f25632ddb8e9 100644 (file)
@@ -31,7 +31,6 @@
 
 #include "QAD.h" 
 #include "QAD_Splitter.h" 
-#include "QAD_PyInterp.h"
 
 // QT Includes
 #include <qwidget.h>
@@ -41,6 +40,7 @@ class QAD_RightFrame;
 class QAD_LeftFrame;
 class QAD_Splitter;
 class QAD_Study;
+class QAD_PyInterp;
 
 enum ViewType {
   VIEW_OCC,