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;
QEvent* PyInterp_Request::getEvent()
{
- if ( !myEvent && !IsSync() )
+ //if ( !myEvent && !IsSync() )
+ if ( !myEvent )
myEvent = createEvent();
return myEvent;
}
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() )
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(){
}
-// 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
PyInterp_base::~PyInterp_base()
{
- PyLockWrapper aLock(_tstate);
- //Py_EndInterpreter(_tstate);
}
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();
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() ;
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();
//#include <pthread.h> // must be before Python.h !
#include <Python.h> // must be before qt includes ...
+#include <compile.h> // Python include needed for versions before 2.4. Included in Python.h now.
+#include <eval.h> // 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 ---"
{
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();
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:
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();
}
}
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();
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
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__
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();
}
}
}
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();
}
}
}
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();
}
}
}
aObject.latin1(),
aParent.latin1() ) );
if( !res ) {
- // VSR: this method may not be implemented in Python module
PyErr_Print();
- //PyErr_Clear();
}
else {
// parse return value
sipPopup.get(),
aContext.latin1() ) );
if( !res1 ) {
- // VSR: this method may not be implemented in Python module
PyErr_Print();
- //PyErr_Clear();
}
}
aObject.latin1(),
aParent.latin1() ) );
if( !res2 ) {
- // VSR: this method may not be implemented in Python module
PyErr_Print();
- //PyErr_Clear();
}
} //__CALL_OLD_METHODS__
}
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();
}
}
}
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__
*/
SCRUTE(KERNEL_PYTHON::_gtstate);
_tstate = KERNEL_PYTHON::_gtstate;
- //PyEval_AcquireLock();
- //PyThreadState_Swap(_tstate);
PyEval_AcquireThread(_tstate);
SCRUTE(_tstate);
PyEval_ReleaseThread(_tstate);
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
*/
SalomeApp_Application::~SalomeApp_Application()
{
- SalomeApp_EventFilter::Destroy();
+ // Do not destroy. It's a singleton !
+ //SalomeApp_EventFilter::Destroy();
}
/*!Start application.*/
/*!\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
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;
}
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;
}
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;
}
{
INFOS( "salome_shared_modules_module == NULL" );
PyErr_Print();
- PyErr_Clear();
}
PyEval_ReleaseThread( KERNEL_PYTHON::_gtstate );