#include <vector>
#include "PyInterp_base.h" // this include must be first (see PyInterp_base.h)!
-#include <Container_init_python.hxx>
#include <cStringIO.h>
-#include <utilities.h>
-
-
using namespace std;
-
-//#ifdef _DEBUG_
-//static int MYDEBUG = 1;
-//static int MYPYDEBUG = 1;
-//#else
-//static int MYDEBUG = 0;
-//static int MYPYDEBUG = 0;
-//#endif
-
-
PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState):
myThreadState(theThreadState),
- mySaveThreadState(KERNEL_PYTHON::_gtstate)
+ mySaveThreadState(0)
{
- PyEval_AcquireLock();
- mySaveThreadState = PyThreadState_Swap(myThreadState); // store previous current in save,
- // set local in current
-// if(MYDEBUG) MESSAGE(" PyLockWrapper "<<this<<" aqcuired: new thread state "<<myThreadState<<" ; old thread state "<<mySaveThreadState);
+#if defined(USE_GILSTATE)
+ if (myThreadState->interp == PyInterp_base::_interp) {
+ _savestate = PyGILState_Ensure();
+ } else {
+ PyEval_AcquireThread(myThreadState);
+ }
+#else
+ PyEval_AcquireThread(myThreadState);
+#endif
}
-
-PyLockWrapper::~PyLockWrapper(){
- PyThreadState_Swap(mySaveThreadState); // restore previous current (no need to get local,
- PyEval_ReleaseLock(); // local thread state* already in _tstate
-// if(MYDEBUG) MESSAGE(" PyLockWrapper "<<this<<" released: new thread state "<<mySaveThreadState);
+PyLockWrapper::~PyLockWrapper()
+{
+#if defined(USE_GILSTATE)
+ if (myThreadState->interp == PyInterp_base::_interp) {
+ PyGILState_Release(_savestate);
+ } else {
+ PyEval_ReleaseThread(myThreadState);
+ }
+#else
+ PyEval_ReleaseThread(myThreadState);
+#endif
}
-
class PyReleaseLock{
public:
~PyReleaseLock(){
-// if(MYPYDEBUG) MESSAGE("~PyReleaseLock()");
PyEval_ReleaseLock();
}
};
}
-// 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(): _tstate(0), _vout(0), _verr(0), _g(0), _atFirst(true)
{
-// if(MYPYDEBUG) MESSAGE("PyInterp_base::PyInterp_base() - this = "<<this);
}
PyInterp_base::~PyInterp_base()
{
-// if(MYPYDEBUG) MESSAGE("PyInterp_base::~PyInterp_base() - this = "<<this);
- PyLockWrapper aLock(_tstate);
- //Py_EndInterpreter(_tstate);
}
init_python();
// Here the global lock is released
-// if(MYPYDEBUG) MESSAGE("PyInterp_base::initialize() - this = "<<this<<"; _gtstate = "<<_gtstate);
-
- // The lock will be acquired in initState. Make provision to release it on exit
- PyReleaseLock aReleaseLock;
initState();
+
+ PyLockWrapper aLock= GetLockWrapper();
+
initContext();
// used to interpret & compile commands
PyObjWrapper m(PyImport_ImportModule("codeop"));
if(!m){
-// INFOS("PyInterp_base::initialize() - PyImport_ImportModule('codeop') failed");
PyErr_Print();
- ASSERT(0);
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();
}
void PyInterp_base::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
- */
- 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();
-// }
+ _atFirst = false;
+ if (Py_IsInitialized())
+ return;
+
+ // Python is not initialized
+ 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
}
string PyInterp_base::getbanner()
{
+ // Should we take the lock ?
+ // PyEval_RestoreThread(_tstate);
string aBanner("Python ");
aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
aBanner = aBanner + "\ntype help to get general information on environment\n";
+ //PyEval_SaveThread();
return aBanner;
}
PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
-// if(MYPYDEBUG) MESSAGE("PyInterp_base::initRun() - this = "<<this<<"; _verr = "<<_verr<<"; _vout = "<<_vout);
return 0;
}
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 *)&v,context,context));
-#endif
+ //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
+ // 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();
// Reset redirected outputs before treatment
PySys_SetObject("stderr",_verr);
PySys_SetObject("stdout",_vout);
-
+
PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
-
+
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__"));
+
return ier;
}
string aRet(PyString_AsString(v));
return aRet;
}
-