diff --git a/panda/src/pipeline/pythonThread.cxx b/panda/src/pipeline/pythonThread.cxx index 12b7d4eadf..b9b7e4ba5a 100644 --- a/panda/src/pipeline/pythonThread.cxx +++ b/panda/src/pipeline/pythonThread.cxx @@ -54,9 +54,11 @@ PythonThread(PyObject *function, PyObject *args, } } +#ifndef SIMPLE_THREADS // Ensure that the Python threading system is initialized and ready // to go. PyEval_InitThreads(); +#endif } //////////////////////////////////////////////////////////////////// @@ -102,9 +104,16 @@ join() { void PythonThread:: thread_main() { // Create a new Python thread state data structure, so Python can - // properly lock itself. - PyGILState_STATE gstate; - gstate = PyGILState_Ensure(); + // properly lock itself. We can't use the PyGILState interface, + // which assumes we are using true OS-level threading (and we might + // be just using SIMPLE_THREADS). PyGILState enforces policies like + // only one thread state per OS-level thread, which is not true in + // the case of SIMPLE_THREADS. + + PyThreadState *orig_thread_state = PyThreadState_Get(); + PyInterpreterState *istate = orig_thread_state->interp; + PyThreadState *new_thread_state = PyThreadState_New(istate); + PyThreadState_Swap(new_thread_state); // Call the user's function. _result = PyObject_Call(_function, _args, NULL); @@ -112,8 +121,9 @@ thread_main() { handle_python_exception(); } - // Release the thread state data structure. - PyGILState_Release(gstate); + PyThreadState_Swap(orig_thread_state); + PyThreadState_Clear(new_thread_state); + PyThreadState_Delete(new_thread_state); } ////////////////////////////////////////////////////////////////////