X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9e58eb5674cfac859568c9a4b1030012e1f0eb64..b515af7a75c346262c6a4fb17f613aab83227d65:/wxPython/src/helpers.cpp?ds=inline diff --git a/wxPython/src/helpers.cpp b/wxPython/src/helpers.cpp index 5030bead5f..f2d08f0fcb 100644 --- a/wxPython/src/helpers.cpp +++ b/wxPython/src/helpers.cpp @@ -49,9 +49,10 @@ bool wxPyDoingCleanup = False; struct wxPyThreadState { unsigned long tid; PyThreadState* tstate; + int blocked; wxPyThreadState(unsigned long _tid=0, PyThreadState* _tstate=NULL) - : tid(_tid), tstate(_tstate) {} + : tid(_tid), tstate(_tstate), blocked(1) {} }; #include @@ -598,7 +599,7 @@ static void rsoPass2(const char* name) } // Find the object instance - obj = PyDict_GetItemString(wxPython_dict, dropwx(name)); + obj = PyDict_GetItemString(wxPython_dict, (char*)dropwx(name)); wxCHECK_RET(obj != NULL, wxT("Unable to find stock object")); wxCHECK_RET(wxPySwigInstance_Check(obj), wxT("Not a swig instance")); @@ -614,12 +615,12 @@ static void rsoPass3(const char* name, const char* classname, void* ptr) PyObject* ptrobj; // Find the object instance - obj = PyDict_GetItemString(wxPython_dict, dropwx(name)); + obj = PyDict_GetItemString(wxPython_dict, (char*)dropwx(name)); wxCHECK_RET(obj != NULL, wxT("Unable to find stock object")); wxCHECK_RET(wxPySwigInstance_Check(obj), wxT("Not a swig instance")); // Find the class object and put it back in the instance - classobj = PyDict_GetItemString(wxPython_dict, dropwx(classname)); + classobj = PyDict_GetItemString(wxPython_dict, (char*)dropwx(classname)); wxCHECK_RET(classobj != NULL, wxT("Unable to find stock class object")); PyObject_SetAttrString(obj, "__class__", classobj); @@ -633,8 +634,6 @@ static void rsoPass3(const char* name, const char* classname, void* ptr) void wxPy_ReinitStockObjects(int pass) { - PyObject* obj; - PyObject* ptrobj; #define REINITOBJ(name, classname) \ if (pass == 1) { name = (classname*)0xC0C0C0C0; } \ @@ -897,21 +896,21 @@ unsigned long wxPyGetCurrentThreadId() { return wxThread::GetCurrentId(); } -static PyThreadState* gs_shutdownTState; +static wxPyThreadState gs_shutdownTState; static -PyThreadState* wxPyGetThreadState() { +wxPyThreadState* wxPyGetThreadState() { if (wxPyTMutex == NULL) // Python is shutting down... - return gs_shutdownTState; + return &gs_shutdownTState; unsigned long ctid = wxPyGetCurrentThreadId(); - PyThreadState* tstate = NULL; + wxPyThreadState* tstate = NULL; wxPyTMutex->Lock(); for(size_t i=0; i < wxPyTStates->GetCount(); i++) { wxPyThreadState& info = wxPyTStates->Item(i); if (info.tid == ctid) { - tstate = info.tstate; + tstate = &info; break; } } @@ -920,10 +919,11 @@ PyThreadState* wxPyGetThreadState() { return tstate; } + static void wxPySaveThreadState(PyThreadState* tstate) { if (wxPyTMutex == NULL) { // Python is shutting down, assume a single thread... - gs_shutdownTState = tstate; + gs_shutdownTState.tstate = tstate; return; } unsigned long ctid = wxPyGetCurrentThreadId(); @@ -952,6 +952,7 @@ void wxPySaveThreadState(PyThreadState* tstate) { #endif + // Calls from Python to wxWindows code are wrapped in calls to these // functions: @@ -959,6 +960,7 @@ PyThreadState* wxPyBeginAllowThreads() { #ifdef WXP_WITH_THREAD PyThreadState* saved = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS; wxPySaveThreadState(saved); + wxPyGetThreadState()->blocked -= 1; return saved; #else return NULL; @@ -967,6 +969,7 @@ PyThreadState* wxPyBeginAllowThreads() { void wxPyEndAllowThreads(PyThreadState* saved) { #ifdef WXP_WITH_THREAD + wxPyGetThreadState()->blocked += 1; PyEval_RestoreThread(saved); // Py_END_ALLOW_THREADS; #endif } @@ -978,17 +981,21 @@ void wxPyEndAllowThreads(PyThreadState* saved) { void wxPyBeginBlockThreads() { #ifdef WXP_WITH_THREAD - PyThreadState* tstate = wxPyGetThreadState(); - PyEval_RestoreThread(tstate); + wxPyThreadState* tstate = wxPyGetThreadState(); + if (tstate->blocked++ == 0) { // if nested calls then do nothing + PyEval_RestoreThread(tstate->tstate); + } #endif } void wxPyEndBlockThreads() { #ifdef WXP_WITH_THREAD - // Is there any need to save it again? - // PyThreadState* tstate = - PyEval_SaveThread(); + wxPyThreadState* tstate = wxPyGetThreadState(); + tstate->blocked -= 1; + if ( tstate->blocked == 0) { // if nested calls then do nothing + PyEval_SaveThread(); + } #endif } @@ -1338,31 +1345,34 @@ void wxPyCallback::EventThunker(wxEvent& event) { arg = wxPyConstructObject((void*)&event, className); } - // Call the event handler, passing the event object - tuple = PyTuple_New(1); - PyTuple_SET_ITEM(tuple, 0, arg); // steals ref to arg - result = PyEval_CallObject(func, tuple); - if ( result ) { - Py_DECREF(result); // result is ignored, but we still need to decref it - PyErr_Clear(); // Just in case... - } else { + if (!arg) { PyErr_Print(); - } - - if ( checkSkip ) { - // if the event object was one of our special types and - // it had been cloned, then we need to extract the Skipped - // value from the original and set it in the clone. - result = PyObject_CallMethod(arg, "GetSkipped", ""); + } else { + // Call the event handler, passing the event object + tuple = PyTuple_New(1); + PyTuple_SET_ITEM(tuple, 0, arg); // steals ref to arg + result = PyEval_CallObject(func, tuple); if ( result ) { - event.Skip(PyInt_AsLong(result)); - Py_DECREF(result); + Py_DECREF(result); // result is ignored, but we still need to decref it + PyErr_Clear(); // Just in case... } else { PyErr_Print(); } - } - Py_DECREF(tuple); + if ( checkSkip ) { + // if the event object was one of our special types and + // it had been cloned, then we need to extract the Skipped + // value from the original and set it in the clone. + result = PyObject_CallMethod(arg, "GetSkipped", ""); + if ( result ) { + event.Skip(PyInt_AsLong(result)); + Py_DECREF(result); + } else { + PyErr_Print(); + } + } + Py_DECREF(tuple); + } wxPyEndBlockThreads(); }