From: Robin Dunn Date: Sun, 24 Oct 1999 05:16:56 +0000 (+0000) Subject: Squashed another threading and interpreter lock bug X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/99a49d3e6779fc1a97a3469f546d7dd580f07e3a Squashed another threading and interpreter lock bug git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4155 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/utils/wxPython/src/helpers.cpp b/utils/wxPython/src/helpers.cpp index 09ead8df34..1ea735c8c7 100644 --- a/utils/wxPython/src/helpers.cpp +++ b/utils/wxPython/src/helpers.cpp @@ -282,37 +282,31 @@ PyObject* wxPyConstructObject(void* ptr, char* className) { //--------------------------------------------------------------------------- -//static bool _wxPyInEvent = false; -//static unsigned int _wxPyNestCount = 0; +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. + // 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. // - // 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.) - // - // until I know better, this is how I am doing it instead: #ifdef WXP_WITH_THREAD - PyEval_RestoreThread(wxPyEventThreadState); -// _wxPyNestCount += 1; -// if (_wxPyNestCount == 1) -// return TRUE; -// else + _wxPyNestCount += 1; + if (wxPyEventThreadState != myPyThreadState_Get()) { + PyEval_RestoreThread(wxPyEventThreadState); + return TRUE; + } + else #endif return FALSE; } @@ -320,11 +314,10 @@ HELPEREXPORT bool wxPyRestoreThread() { HELPEREXPORT void wxPySaveThread(bool doSave) { #ifdef WXP_WITH_THREAD -// if (doSave) { + if (doSave) { wxPyEventThreadState = PyEval_SaveThread(); -// _wxPyInEvent = false; -// } -// _wxPyNestCount -= 1; + } + _wxPyNestCount -= 1; #endif } @@ -351,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; diff --git a/utils/wxPython/src/helpers.h b/utils/wxPython/src/helpers.h index dec6df12ad..fbe3318fcd 100644 --- a/utils/wxPython/src/helpers.h +++ b/utils/wxPython/src/helpers.h @@ -415,13 +415,15 @@ private: #define IMP_PYCALLBACK_BOOL_DC4DBLBOOL(CLASS, PCLASS, CBNAME) \ bool CLASS::CBNAME(wxDC& a, double b, double c, double d, double e, bool f) { \ bool doSave = wxPyRestoreThread(); \ + bool rval; \ if (m_myInst.findCallback(#CBNAME)) \ - return m_myInst.callCallback(Py_BuildValue("(Oddddi)", \ + rval = m_myInst.callCallback(Py_BuildValue("(Oddddi)", \ wxPyConstructObject(&a, "wxDC"), \ b, c, d, e, (int)f)); \ else \ - return PCLASS::CBNAME(a, b, c, d, e, f); \ + rval = PCLASS::CBNAME(a, b, c, d, e, f); \ wxPySaveThread(doSave); \ + return rval; \ } \ bool CLASS::base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {\ return PCLASS::CBNAME(a, b, c, d, e, f); \