]> git.saurik.com Git - wxWidgets.git/commitdiff
Squashed another threading and interpreter lock bug
authorRobin Dunn <robin@alldunn.com>
Sun, 24 Oct 1999 05:16:56 +0000 (05:16 +0000)
committerRobin Dunn <robin@alldunn.com>
Sun, 24 Oct 1999 05:16:56 +0000 (05:16 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4155 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

utils/wxPython/src/helpers.cpp
utils/wxPython/src/helpers.h

index 09ead8df34b2b7922717571f797d566d67847519..1ea735c8c7a02a7a53bb327e476b7313c289a77f 100644 (file)
@@ -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;
index dec6df12add8a8b429be796b3006ca950d424115..fbe3318fcdc50ad358f75dca09154994a4ab914c 100644 (file)
@@ -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);                                        \