Squashed another threading and interpreter lock bug

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4155 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
1999-10-24 05:16:56 +00:00
parent 2b2739754f
commit 99a49d3e67
2 changed files with 26 additions and 32 deletions

View 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;
static PyThreadState* myPyThreadState_Get() {
PyThreadState* current;
current = PyThreadState_Swap(NULL);
PyThreadState_Swap(current);
return current;
}
HELPEREXPORT bool wxPyRestoreThread() { HELPEREXPORT bool wxPyRestoreThread() {
// #ifdef WXP_WITH_THREAD
// //if (wxPyEventThreadState != PyThreadState_Get()) {
// if (! _wxPyInEvent) {
// PyEval_RestoreThread(wxPyEventThreadState);
// _wxPyInEvent = true;
// return TRUE;
// } else
// #endif
// return FALSE;
// NOTE: The Python API docs state that if a thread already has the // NOTE: The Python API docs state that if a thread already has the
// interpreter lock and calls PyEval_RestoreThread again a deadlock // interpreter lock and calls PyEval_RestoreThread again a deadlock
// occurs, so I put in the above code as a guard condition since there are // occurs, so I put in this code as a guard condition since there are
// many possibilites for nested events and callbacks in wxPython. // 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 #ifdef WXP_WITH_THREAD
PyEval_RestoreThread(wxPyEventThreadState); _wxPyNestCount += 1;
// _wxPyNestCount += 1; if (wxPyEventThreadState != myPyThreadState_Get()) {
// if (_wxPyNestCount == 1) PyEval_RestoreThread(wxPyEventThreadState);
// return TRUE; return TRUE;
// else }
else
#endif #endif
return FALSE; return FALSE;
} }
@@ -320,11 +314,10 @@ HELPEREXPORT bool wxPyRestoreThread() {
HELPEREXPORT void wxPySaveThread(bool doSave) { HELPEREXPORT void wxPySaveThread(bool doSave) {
#ifdef WXP_WITH_THREAD #ifdef WXP_WITH_THREAD
// if (doSave) { if (doSave) {
wxPyEventThreadState = PyEval_SaveThread(); wxPyEventThreadState = PyEval_SaveThread();
// _wxPyInEvent = false; }
// } _wxPyNestCount -= 1;
// _wxPyNestCount -= 1;
#endif #endif
} }
@@ -351,7 +344,6 @@ wxPyCallback::~wxPyCallback() {
// This function is used for all events destined for Python event handlers. // This function is used for all events destined for Python event handlers.
void wxPyCallback::EventThunker(wxEvent& event) { void wxPyCallback::EventThunker(wxEvent& event) {
wxPyCallback* cb = (wxPyCallback*)event.m_callbackUserData; wxPyCallback* cb = (wxPyCallback*)event.m_callbackUserData;

View File

@@ -415,13 +415,15 @@ private:
#define IMP_PYCALLBACK_BOOL_DC4DBLBOOL(CLASS, PCLASS, CBNAME) \ #define IMP_PYCALLBACK_BOOL_DC4DBLBOOL(CLASS, PCLASS, CBNAME) \
bool CLASS::CBNAME(wxDC& a, double b, double c, double d, double e, bool f) { \ bool CLASS::CBNAME(wxDC& a, double b, double c, double d, double e, bool f) { \
bool doSave = wxPyRestoreThread(); \ bool doSave = wxPyRestoreThread(); \
bool rval; \
if (m_myInst.findCallback(#CBNAME)) \ if (m_myInst.findCallback(#CBNAME)) \
return m_myInst.callCallback(Py_BuildValue("(Oddddi)", \ rval = m_myInst.callCallback(Py_BuildValue("(Oddddi)", \
wxPyConstructObject(&a, "wxDC"), \ wxPyConstructObject(&a, "wxDC"), \
b, c, d, e, (int)f)); \ b, c, d, e, (int)f)); \
else \ else \
return PCLASS::CBNAME(a, b, c, d, e, f); \ rval = PCLASS::CBNAME(a, b, c, d, e, f); \
wxPySaveThread(doSave); \ wxPySaveThread(doSave); \
return rval; \
} \ } \
bool CLASS::base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {\ 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); \ return PCLASS::CBNAME(a, b, c, d, e, f); \