X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8f17924e7389618db0ac792f2b53e69d7e4bb4ec..bf57d1adacf489fb1a9a2167b909b279cdf3e0f6:/utils/wxPython/src/helpers.cpp diff --git a/utils/wxPython/src/helpers.cpp b/utils/wxPython/src/helpers.cpp index df05338a93..47c2f51730 100644 --- a/utils/wxPython/src/helpers.cpp +++ b/utils/wxPython/src/helpers.cpp @@ -121,6 +121,10 @@ int wxPyApp::MainLoop(void) { // wxcmodule is imported. (Before there is a wxApp object.) void __wxPreStart() { +#ifdef WXP_WITH_THREAD + PyEval_InitThreads(); +#endif + // Bail out if there is already windows created. This means that the // toolkit has already been initialized, as in embedding wxPython in // a C++ wxWindows app. @@ -278,36 +282,30 @@ PyObject* wxPyConstructObject(void* ptr, char* className) { //--------------------------------------------------------------------------- -//static bool _wxPyInEvent = false; static unsigned int _wxPyNestCount = 0; -HELPEREXPORT bool wxPyRestoreThread() { -// #ifdef WXP_WITH_THREAD -// //if (wxPyEventThreadState != PyThreadState_Get()) { -// if (! _wxPyInEvent) { -// PyEval_RestoreThread(wxPyEventThreadState); -// _wxPyInEvent = true; -// return TRUE; -// } else -// #endif -// return FALSE; +static PyThreadState* myPyThreadState_Get() { + PyThreadState* current; + current = PyThreadState_Swap(NULL); + PyThreadState_Swap(current); + return current; +} + +HELPEREXPORT bool wxPyRestoreThread() { // NOTE: The Python API docs state that if a thread already has the // interpreter lock and calls PyEval_RestoreThread again a deadlock - // occurs, so I put in the above code as a guard condition since there are - // many possibilites for nested events and callbacks in wxPython. - // - // Unfortunately, it seems like somebody was lying (or I'm not - // understanding...) because each of the nested calls to this function - // MUST call PyEval_RestoreThread or Python pukes with a thread error (at - // least on Win32.) + // occurs, so I put in this code as a guard condition since there are + // many possibilites for nested events and callbacks in wxPython. If + // The current thread is our thread, then we can assume that we + // already have the lock. (I hope!) // - // until I know better, this is how I am doing it instead: #ifdef WXP_WITH_THREAD - PyEval_RestoreThread(wxPyEventThreadState); _wxPyNestCount += 1; - if (_wxPyNestCount == 1) + if (wxPyEventThreadState != myPyThreadState_Get()) { + PyEval_RestoreThread(wxPyEventThreadState); return TRUE; + } else #endif return FALSE; @@ -317,8 +315,7 @@ HELPEREXPORT bool wxPyRestoreThread() { HELPEREXPORT void wxPySaveThread(bool doSave) { #ifdef WXP_WITH_THREAD if (doSave) { - PyEval_SaveThread(); - //_wxPyInEvent = false; + wxPyEventThreadState = PyEval_SaveThread(); } _wxPyNestCount -= 1; #endif @@ -347,7 +344,6 @@ wxPyCallback::~wxPyCallback() { - // This function is used for all events destined for Python event handlers. void wxPyCallback::EventThunker(wxEvent& event) { wxPyCallback* cb = (wxPyCallback*)event.m_callbackUserData;