From: prascle Date: Tue, 6 Dec 2005 17:53:45 +0000 (+0000) Subject: PR: 2nd modifs from Christian Caremoli, embedded interpretor X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2FBR_V3_1_0a3_Python;p=modules%2Fgui.git PR: 2nd modifs from Christian Caremoli, embedded interpretor --- diff --git a/src/PyInterp/PyInterp_Dispatcher.cxx b/src/PyInterp/PyInterp_Dispatcher.cxx index a86e62c1d..f46d0a4a9 100755 --- a/src/PyInterp/PyInterp_Dispatcher.cxx +++ b/src/PyInterp/PyInterp_Dispatcher.cxx @@ -33,7 +33,8 @@ void PyInterp_Request::process() cerr << "----------PyInterp_Request::process" << endl; myMutex.lock(); - if ( !IsSync() && getListener() && getEvent() ) + //if ( !IsSync() && getListener() && getEvent() ) + if ( getListener() && getEvent() ) postEvent(); myMutex.unlock(); cerr << "---------------------------PyInterp_Request::process" << endl; @@ -59,7 +60,8 @@ QEvent* PyInterp_Request::createEvent() const QEvent* PyInterp_Request::getEvent() { - if ( !myEvent && !IsSync() ) + //if ( !myEvent && !IsSync() ) + if ( !myEvent ) myEvent = createEvent(); return myEvent; } @@ -152,7 +154,7 @@ void PyInterp_Dispatcher::Exec( PyInterp_Request* theRequest ) if ( theRequest->IsSync() ) // synchronous processing - nothing is done if dispatcher is busy! processRequest( theRequest ); else { // asynchronous processing - cerr << "PyInterp_Dispatcher::Exec request delayed" << endl; + cerr << "PyInterp_Dispatcher::Exec request deferred" << endl; myQueueMutex.lock(); myQueue.push_back( theRequest ); if ( theRequest->getListener() ) diff --git a/src/PyInterp/PyInterp_base.cxx b/src/PyInterp/PyInterp_base.cxx index 180df0df9..18d066d7a 100644 --- a/src/PyInterp/PyInterp_base.cxx +++ b/src/PyInterp/PyInterp_base.cxx @@ -22,20 +22,48 @@ PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState): myThreadState(theThreadState), mySaveThreadState(0) { + cerr << "PyLockWrapper::PyLockWrapper" << endl; +#if defined(USE_GILSTATE) + if(myThreadState->interp == PyInterp_base::_interp) + { + cerr << "PyLockWrapper::PyLockWrapper:GILstate" << endl; + _savestate = PyGILState_Ensure(); + cerr << "------------------------PyLockWrapper::PyLockWrapper:GILstate" << endl; + } + else + { + cerr << "PyLockWrapper::PyLockWrapper:PyEval_AcquireThread" << endl; + PyEval_AcquireThread(myThreadState); + cerr << "------------------------PyLockWrapper::PyLockWrapper:PyEval_AcquireThread" << endl; + } +#else PyEval_AcquireThread(myThreadState); - //PyEval_AcquireLock(); - //mySaveThreadState = PyThreadState_Swap(myThreadState); // store previous current in save, - // set local in current +#endif + cerr << "----------------------------PyLockWrapper::PyLockWrapper" << endl; } - -PyLockWrapper::~PyLockWrapper(){ +PyLockWrapper::~PyLockWrapper() +{ + cerr << "PyLockWrapper::~PyLockWrapper" << endl; +#if defined(USE_GILSTATE) + if(myThreadState->interp == PyInterp_base::_interp) + { + cerr << "PyLockWrapper::~PyLockWrapper:GILstate" << endl; + PyGILState_Release(_savestate); + cerr << "------------------------PyLockWrapper::~PyLockWrapper:GILstate" << endl; + } + else + { + cerr << "PyLockWrapper::~PyLockWrapper:PyEval_ReleaseThread" << endl; + PyEval_ReleaseThread(myThreadState); + cerr << "------------------------PyLockWrapper::~PyLockWrapper:PyEval_ReleaseThread" << endl; + } +#else PyEval_ReleaseThread(myThreadState); - //PyThreadState_Swap(mySaveThreadState); // restore previous current (no need to get local, - //PyEval_ReleaseLock(); // local thread state* already in _tstate +#endif + cerr << "----------------------------PyLockWrapper::~PyLockWrapper" << endl; } - class PyReleaseLock{ public: ~PyReleaseLock(){ @@ -49,14 +77,16 @@ PyLockWrapper PyInterp_base::GetLockWrapper(){ } -// main python interpreter +// main python interpreter (static attributes) -//PyThreadState *PyInterp_base::_gtstate = 0; // force 0 before execution int PyInterp_base::_argc = 1; char* PyInterp_base::_argv[] = {""}; PyObject *PyInterp_base::builtinmodule = NULL; +PyThreadState *PyInterp_base::_gtstate = NULL; +PyInterpreterState *PyInterp_base::_interp = NULL; + /*! * basic constructor here : herited classes constructors must call initalize() method @@ -68,8 +98,6 @@ PyInterp_base::PyInterp_base(): _tstate(0), _vout(0), _verr(0), _g(0), _atFirst( PyInterp_base::~PyInterp_base() { - PyLockWrapper aLock(_tstate); - //Py_EndInterpreter(_tstate); } @@ -88,9 +116,6 @@ void PyInterp_base::initialize() init_python(); // Here the global lock is released - // The lock will be acquired in initState. Make provision to release it on exit - // PyReleaseLock aReleaseLock; - initState(); PyLockWrapper aLock= GetLockWrapper(); @@ -101,47 +126,40 @@ void PyInterp_base::initialize() PyObjWrapper m(PyImport_ImportModule("codeop")); if(!m){ PyErr_Print(); - //PyEval_SaveThread(); return; } // 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); // All the initRun outputs are redirected to the standard output (console) initRun(); - //PyEval_SaveThread(); + cerr << "---------------------------PyInterp_base::initialize" << endl; } void PyInterp_base::init_python() { - static PyThreadState *_gtstate = 0; - _atFirst = false; if (Py_IsInitialized()) return; + // Python is not initialized + cerr << "Python not initialized" << endl; Py_SetProgramName(_argv[0]); Py_Initialize(); // Initialize the interpreter PySys_SetArgv(_argc, _argv); PyEval_InitThreads(); // Create (and acquire) the interpreter lock + _interp = PyThreadState_Get()->interp; _gtstate = PyEval_SaveThread(); // Release global thread state - // There the thread state is NULL -// if(!_gtstate){ -// PyReleaseLock aReleaseLock; -// Py_Initialize(); // Initialize the interpreter -// PyEval_InitThreads(); // Initialize and acquire the global interpreter lock -// PySys_SetArgv(_argc,_argv); // initialize sys.argv -// _gtstate = PyThreadState_Get(); -// } + cerr << "-------------------------Python not initialized" << endl; } string PyInterp_base::getbanner() { + // Should we take the lock ? // PyEval_RestoreThread(_tstate); string aBanner("Python "); aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ; @@ -197,11 +215,7 @@ int compile_command(const char *command,PyObject *context) return 1; }else{ // Complete and correct text. We evaluate it. -#ifndef WNT - PyObjWrapper r(PyEval_EvalCode(v,context,context)); -#else PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,context,context)); -#endif if(!r){ // Execution error. We return -1 PyErr_Print(); diff --git a/src/PyInterp/PyInterp_base.h b/src/PyInterp/PyInterp_base.h index 469c0f409..cd92228ac 100644 --- a/src/PyInterp/PyInterp_base.h +++ b/src/PyInterp/PyInterp_base.h @@ -23,9 +23,12 @@ //#include // must be before Python.h ! #include // must be before qt includes ... +#include // Python include needed for versions before 2.4. Included in Python.h now. +#include // Python include needed for versions before 2.4. Included in Python.h now. -#ifndef WNT -extern "C" PyObject * PyEval_EvalCode(PyObject *co, PyObject *g, PyObject *l); +/* For 2.3, use the PyGILState_ calls */ +#if (PY_VERSION_HEX >= 0x02030000) +#define USE_GILSTATE #endif #define TOP_HISTORY_PY "--- top of history ---" @@ -35,17 +38,21 @@ class PYINTERP_EXPORT PyLockWrapper { PyThreadState* myThreadState; PyThreadState* mySaveThreadState; +#if defined(USE_GILSTATE) + PyGILState_STATE _savestate ; +#endif public: PyLockWrapper(PyThreadState* theThreadState); ~PyLockWrapper(); }; - class PYINTERP_EXPORT PyInterp_base{ public: static int _argc; static char* _argv[]; static PyObject *builtinmodule; + static PyThreadState *_gtstate; + static PyInterpreterState *_interp; PyInterp_base(); ~PyInterp_base(); diff --git a/src/PythonConsole/PythonConsole_PyEditor.cxx b/src/PythonConsole/PythonConsole_PyEditor.cxx index 83829d19d..f01018afd 100755 --- a/src/PythonConsole/PythonConsole_PyEditor.cxx +++ b/src/PythonConsole/PythonConsole_PyEditor.cxx @@ -56,8 +56,8 @@ static QString DOTS_PROMPT = "... "; class ExecCommand : public PyInterp_LockRequest { public: - ExecCommand(PyInterp_base* theInterp, const char* theCommand, PythonConsole_PyEditor* theListener) -: PyInterp_LockRequest( theInterp, theListener ), myCommand(theCommand), myState( PyInterp_Event::OK ) + ExecCommand(PyInterp_base* theInterp, const char* theCommand, PythonConsole_PyEditor* theListener,bool sync = false) +: PyInterp_LockRequest( theInterp, theListener,sync ), myCommand(theCommand), myState( PyInterp_Event::OK ) {} protected: diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx index 600699ea8..91f98c9e7 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx +++ b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx @@ -489,9 +489,7 @@ void SALOME_PYQT_Module::init( CAM_Application* app ) if(PyObject_HasAttrString(myModule , "initialize")){ PyObjWrapper res( PyObject_CallMethod( myModule, "initialize", "" ) ); if( !res ) { - // CCAR already tested // VSR: this method may not be implemented in Python module PyErr_Print(); - //PyErr_Clear(); } } @@ -505,9 +503,7 @@ void SALOME_PYQT_Module::init( CAM_Application* app ) if(PyObject_HasAttrString(myModule , "windows")){ PyObjWrapper res1( PyObject_CallMethod( myModule, "windows", "" ) ); if( !res1 ) { - // VSR: this method may not be implemented in Python module PyErr_Print(); - //PyErr_Clear(); } else { myWindowsMap.clear(); @@ -532,9 +528,7 @@ void SALOME_PYQT_Module::init( CAM_Application* app ) if(PyObject_HasAttrString(myModule , "views")){ PyObjWrapper res2( PyObject_CallMethod( myModule, "views", "" ) ); if( !res2 ) { - // VSR: this method may not be implemented in Python module PyErr_Print(); - //PyErr_Clear(); } else { // parse the return value @@ -589,9 +583,7 @@ void SALOME_PYQT_Module::activate( SUIT_Study* theStudy ) if(PyObject_HasAttrString(myModule , "setSettings")){ PyObjWrapper res( PyObject_CallMethod( myModule, "setSettings", "" ) ); if( !res ) { - // VSR: this method may not be implemented in Python module PyErr_Print(); - //PyErr_Clear(); } } } //__CALL_OLD_METHODS__ @@ -600,9 +592,7 @@ void SALOME_PYQT_Module::activate( SUIT_Study* theStudy ) if(PyObject_HasAttrString(myModule , "activate")){ PyObjWrapper res1( PyObject_CallMethod( myModule, "activate", "" ) ); if( !res1 ) { - // VSR: this method may not be implemented in Python module PyErr_Print(); - //PyErr_Clear(); } } } @@ -622,9 +612,7 @@ void SALOME_PYQT_Module::deactivate( SUIT_Study* theStudy ) if(PyObject_HasAttrString(myModule , "deactivate")){ PyObjWrapper res( PyObject_CallMethod( myModule, "deactivate", "" ) ); if( !res ) { - // VSR: this method may not be implemented in Python module PyErr_Print(); - //PyErr_Clear(); } } } @@ -658,9 +646,7 @@ void SALOME_PYQT_Module::studyChanged( SUIT_Study* theStudy ) if(PyObject_HasAttrString(myModule , "activeStudyChanged")){ PyObjWrapper res( PyObject_CallMethod( myModule, "activeStudyChanged", "i", aStudyId ) ); if( !res ) { - // VSR: this method may not be implemented in Python module PyErr_Print(); - //PyErr_Clear(); } } } @@ -750,9 +736,7 @@ void SALOME_PYQT_Module::contextMenu( const QString& theContext, QPopupMenu* the aObject.latin1(), aParent.latin1() ) ); if( !res ) { - // VSR: this method may not be implemented in Python module PyErr_Print(); - //PyErr_Clear(); } else { // parse return value @@ -780,9 +764,7 @@ void SALOME_PYQT_Module::contextMenu( const QString& theContext, QPopupMenu* the sipPopup.get(), aContext.latin1() ) ); if( !res1 ) { - // VSR: this method may not be implemented in Python module PyErr_Print(); - //PyErr_Clear(); } } @@ -797,9 +779,7 @@ void SALOME_PYQT_Module::contextMenu( const QString& theContext, QPopupMenu* the aObject.latin1(), aParent.latin1() ) ); if( !res2 ) { - // VSR: this method may not be implemented in Python module PyErr_Print(); - //PyErr_Clear(); } } //__CALL_OLD_METHODS__ } @@ -818,9 +798,7 @@ void SALOME_PYQT_Module::guiEvent( const int theId ) if ( PyObject_HasAttrString(myModule , "OnGUIEvent") ) { PyObjWrapper res( PyObject_CallMethod( myModule, "OnGUIEvent", "i", theId ) ); if( !res ) { - // VSR: this method may not be implemented in Python module PyErr_Print(); - //PyErr_Clear(); } } } @@ -939,9 +917,7 @@ void SALOME_PYQT_Module::setWorkSpace() if ( PyObject_HasAttrString(myModule , "setWorkSpace") ) { PyObjWrapper res( PyObject_CallMethod( myModule, "setWorkSpace", "O", pyws.get() ) ); if( !res ) { - // VSR: this method may not be implemented in Python module PyErr_Print(); - //PyErr_Clear(); } } } //__CALL_OLD_METHODS__ diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_PyInterp.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_PyInterp.cxx index 61a323dc8..476ad1f5f 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_PyInterp.cxx +++ b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_PyInterp.cxx @@ -38,8 +38,6 @@ bool SALOME_PYQT_PyInterp::initState() */ SCRUTE(KERNEL_PYTHON::_gtstate); _tstate = KERNEL_PYTHON::_gtstate; - //PyEval_AcquireLock(); - //PyThreadState_Swap(_tstate); PyEval_AcquireThread(_tstate); SCRUTE(_tstate); PyEval_ReleaseThread(_tstate); @@ -69,7 +67,7 @@ int SALOME_PYQT_PyInterp::run(const char *command) PyErr_Print(); return -1; } - PyObject *r = PyEval_EvalCode(code,_g,_g); + PyObject *r = PyEval_EvalCode((PyCodeObject *)code,_g,_g); Py_DECREF(code); if(!r){ // Une erreur s est produite a l execution diff --git a/src/SalomeApp/SalomeApp_Application.cxx b/src/SalomeApp/SalomeApp_Application.cxx index c804b6a63..56d4fc794 100644 --- a/src/SalomeApp/SalomeApp_Application.cxx +++ b/src/SalomeApp/SalomeApp_Application.cxx @@ -80,7 +80,8 @@ SalomeApp_Application::SalomeApp_Application() */ SalomeApp_Application::~SalomeApp_Application() { - SalomeApp_EventFilter::Destroy(); + // Do not destroy. It's a singleton ! + //SalomeApp_EventFilter::Destroy(); } /*!Start application.*/ diff --git a/src/SalomeApp/SalomeApp_PyInterp.cxx b/src/SalomeApp/SalomeApp_PyInterp.cxx index d702d1a59..e9867c323 100755 --- a/src/SalomeApp/SalomeApp_PyInterp.cxx +++ b/src/SalomeApp/SalomeApp_PyInterp.cxx @@ -57,7 +57,7 @@ SalomeApp_PyInterp::~SalomeApp_PyInterp() /*!\class SalomeApp_PyInterp * EDF-CCAR - * Wasashen SALOME uses multi Python interpreter feature, + * When SALOME uses multi Python interpreter feature, * Every study has its own interpreter and thread state (_tstate = Py_NewInterpreter()) * This is fine because every study has its own modules (sys.modules) stdout and stderr * BUT some Python modules must be imported only once. In multi interpreter context Python @@ -85,14 +85,12 @@ bool SalomeApp_PyInterp::initContext() if ( !PythonConsole_PyInterp::initContext() ) return false; - // 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 ); return false; } @@ -102,10 +100,9 @@ bool SalomeApp_PyInterp::initContext() PyObjWrapper m2( PyObject_CallMethod( m1, "init_shared_modules", "O", KERNEL_PYTHON::salome_shared_modules_module ) ); if ( !m2 ) { - MESSAGE( "initContext: problem with init_shared_modules call" ); - PyErr_Print(); - PyErr_Clear(); - ASSERT( 0 ); + MESSAGE( "initContext: problem with init_shared_modules call" ); + PyErr_Print(); + ASSERT( 0 ); return false; } @@ -116,19 +113,13 @@ bool SalomeApp_PyInterp::initContext() void SalomeApp_PyInterp::init_python() { /* - * Initialize the main state (_gtstate) if not already done - * The lock is released on init_python output - * It is the caller responsability to acquire it if needed + * Do nothing + * The initialization has been done in main */ MESSAGE("PyInterp_base::init_python"); ASSERT(KERNEL_PYTHON::_gtstate); // initialisation in main SCRUTE(KERNEL_PYTHON::_gtstate); -// if(!_gtstate){ -// PyReleaseLock aReleaseLock; -// Py_Initialize(); // Initialize the interpreter -// PyEval_InitThreads(); // Initialize and acquire the global interpreter lock -// PySys_SetArgv(_argc,_argv); // initialize sys.argv -// _gtstate = PyThreadState_Get(); -// } + _gtstate=KERNEL_PYTHON::_gtstate; + _interp=KERNEL_PYTHON::_interp; } diff --git a/src/Session/SALOME_Session_Server.cxx b/src/Session/SALOME_Session_Server.cxx index 84c7f7a81..8e86cffa3 100755 --- a/src/Session/SALOME_Session_Server.cxx +++ b/src/Session/SALOME_Session_Server.cxx @@ -295,7 +295,6 @@ int main( int argc, char **argv ) { INFOS( "salome_shared_modules_module == NULL" ); PyErr_Print(); - PyErr_Clear(); } PyEval_ReleaseThread( KERNEL_PYTHON::_gtstate );