[0.3.x] fixed: compability with GILState API

git-svn-id: https://pykd.svn.codeplex.com/svn@86899 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2013-12-20 09:37:05 +00:00 committed by Mikhail I. Izmestev
parent f3e27d30b8
commit 9e00a5a289

View File

@ -94,6 +94,124 @@ void PykdExt::tearDown()
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
class InterprterVirt
{
public:
InterprterVirt()
{
PyThreadState *threadState = PyGILState_GetThisThreadState();
modules = threadState->interp->modules;
modules_reloading = threadState->interp->modules_reloading;
sysdict = threadState->interp->sysdict;
builtins = threadState->interp->builtins;
codec_search_path = threadState->interp->codec_search_path;
codec_search_cache = threadState->interp->codec_search_cache;
codec_error_registry = threadState->interp->codec_error_registry;
newThread = NULL;
}
~InterprterVirt()
{
PyThreadState *threadState =PyGILState_GetThisThreadState();
if ( threadState->interp->modules != modules )
{
Py_DECREF(threadState->interp->modules);
threadState->interp->modules = modules;
}
if ( threadState->interp->modules_reloading != modules_reloading )
{
Py_DECREF(threadState->interp->modules_reloading);
threadState->interp->modules_reloading = modules_reloading;
}
if ( threadState->interp->sysdict != sysdict )
{
Py_DECREF(threadState->interp->sysdict);
threadState->interp->sysdict = sysdict;
}
if ( threadState->interp->builtins != builtins )
{
Py_DECREF(threadState->interp->builtins);
threadState->interp->builtins = builtins;
}
if ( threadState->interp->codec_search_path != codec_search_path )
{
Py_DECREF(threadState->interp->codec_search_path);
threadState->interp->codec_search_path = codec_search_path;
}
if ( threadState->interp->codec_search_cache != codec_search_cache )
{
Py_DECREF(threadState->interp->codec_search_cache);
threadState->interp->codec_search_cache = codec_search_cache;
}
if ( threadState->interp->codec_error_registry != codec_error_registry )
{
Py_DECREF(threadState->interp->codec_error_registry);
threadState->interp->codec_search_cache = codec_error_registry;
}
if (newThread)
{
PyThreadState* current = PyThreadState_Get();
PyThreadState_Swap(newThread);
Py_EndInterpreter(newThread);
PyThreadState_Swap(current);
}
}
void fork()
{
PyThreadState *threadState =PyGILState_GetThisThreadState();
newThread = Py_NewInterpreter();
threadState->interp->modules = newThread->interp->modules;
Py_INCREF(threadState->interp->modules);
threadState->interp->modules_reloading = newThread->interp->modules_reloading;
Py_INCREF(threadState->interp->modules_reloading);
threadState->interp->sysdict = newThread->interp->sysdict;
Py_INCREF(threadState->interp->sysdict);
threadState->interp->builtins = newThread->interp->builtins;
Py_INCREF(threadState->interp->builtins);
threadState->interp->codec_search_path = newThread->interp->codec_search_path;
Py_INCREF(threadState->interp->codec_search_path);
threadState->interp->codec_search_cache = newThread->interp->codec_search_cache;
Py_INCREF(threadState->interp->codec_search_cache);
threadState->interp->codec_error_registry = newThread->interp->codec_error_registry;
Py_INCREF(threadState->interp->codec_error_registry);
PyThreadState_Swap(threadState);
}
private:
PyObject *modules;
PyObject *sysdict;
PyObject *builtins;
PyObject *modules_reloading;
PyObject *codec_search_path;
PyObject *codec_search_cache;
PyObject *codec_error_registry;
PyThreadState *newThread;
};
KDLIB_EXT_COMMAND_METHOD_IMPL(PykdExt, py) KDLIB_EXT_COMMAND_METHOD_IMPL(PykdExt, py)
{ {
ArgsList args = getArgs(); ArgsList args = getArgs();
@ -175,75 +293,57 @@ KDLIB_EXT_COMMAND_METHOD_IMPL(PykdExt, py)
PyEval_RestoreThread( m_pyState ); PyEval_RestoreThread( m_pyState );
if ( !global ) do {
{
globalState = PyThreadState_Swap( NULL );
localState = Py_NewInterpreter(); InterprterVirt interpretrVirt;
python::object sys = python::import("sys"); if ( !global )
sys.attr("stdout") = python::object( pykd::DbgOut() );
sys.attr("stderr") = python::object( pykd::DbgOut() );
sys.attr("stdin") = python::object( pykd::DbgIn() );
}
if ( args.size() == 0 )
{
startConsole();
}
else
{
std::string scriptFileName = getScriptFileName( args[0] );
// óñòàíàâèëèâàåì ïèòîíîâñêèå àðãóìåíòû
char **pythonArgs = new char* [ args.size() ];
pythonArgs[0] = const_cast<char*>(scriptFileName.c_str());
for ( size_t i = 1; i < args.size(); ++i )
pythonArgs[i] = const_cast<char*>( args[i].c_str() );
PySys_SetArgv( (int)args.size(), pythonArgs );
delete[] pythonArgs;
// ïîëó÷àåì äîñòïó ê ãëîáàëüíîìó ìàïó ( íóæåí äëÿ âûçîâà exec_file )
python::object main = python::import("__main__");
python::object global(main.attr("__dict__"));
try {
PykdInterruptWatch interruptWatch;
python::exec_file( scriptFileName.c_str(), global );
}
catch( python::error_already_set const & )
{ {
printException(); interpretrVirt.fork();
python::object sys = python::import("sys");
sys.attr("stdout") = python::object( pykd::DbgOut() );
sys.attr("stderr") = python::object( pykd::DbgOut() );
sys.attr("stdin") = python::object( pykd::DbgIn() );
} }
}
if ( !global ) if ( args.size() == 0 )
{
PyInterpreterState *interpreter = localState->interp;
while( interpreter->tstate_head != NULL )
{ {
PyThreadState *threadState = (PyThreadState*)(interpreter->tstate_head); startConsole();
PyThreadState_Clear(threadState);
PyThreadState_Swap( NULL );
PyThreadState_Delete(threadState);
} }
else
PyInterpreterState_Clear(interpreter); {
std::string scriptFileName = getScriptFileName( args[0] );
PyInterpreterState_Delete(interpreter); // óñòàíàâèëèâàåì ïèòîíîâñêèå àðãóìåíòû
char **pythonArgs = new char* [ args.size() ];
PyThreadState_Swap( globalState ); pythonArgs[0] = const_cast<char*>(scriptFileName.c_str());
}
for ( size_t i = 1; i < args.size(); ++i )
pythonArgs[i] = const_cast<char*>( args[i].c_str() );
PySys_SetArgv( (int)args.size(), pythonArgs );
delete[] pythonArgs;
// ïîëó÷àåì äîñòïó ê ãëîáàëüíîìó ìàïó ( íóæåí äëÿ âûçîâà exec_file )
python::object main = python::import("__main__");
python::object global(main.attr("__dict__"));
try {
PykdInterruptWatch interruptWatch;
python::exec_file( scriptFileName.c_str(), global );
}
catch( python::error_already_set const & )
{
printException();
}
}
} while( false);
m_pyState = PyEval_SaveThread(); m_pyState = PyEval_SaveThread();