Bugs item #906305, was opened at 2004-02-28 12:44
Message generated for change (Settings changed) made by mhammond
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=551954&aid=906305&group_id=78018
Category: win32
Group: None
>Status: Closed
>Resolution: Fixed
Priority: 5
Submitted By: Greg Chapman (glchapman)
Assigned to: Nobody/Anonymous (nobody)
Summary: Problems (deadlock) with calling CEnterLeavePython.acquire
Initial Comment:
PyWndProcHWND in win32gui explicitly calls the
acquire method of _celp (a CEnterLeavePython
instance) when handling a WM_NCDESTROY message.
Unfortunately, if this message was not handled by
PyWndProc_Call, _celp.release will already have been
called (just prior to dispatching to oldWndProc), setting
_celp.released to TRUE. Because released == TRUE,
_celp's destructor does not release the GIL, with a
deadlock likely to result. (In my case it did result,
since the WM_NCDESTROY was produced by a call to
win32gui.DestroyWindow).
Perhaps released should be set in the acquire method
rather than in the constructor?
I'm using win32all build 200, Python 2.3.3, and
Windows XP.
----------------------------------------------------------------------
>Comment By: Mark Hammond (mhammond)
Date: 2004-04-07 15:25
Message:
Logged In: YES
user_id=14198
This bug was recently fixed and will be in the next release.
----------------------------------------------------------------------
Comment By: Greg Chapman (glchapman)
Date: 2004-02-28 14:49
Message:
Logged In: YES
user_id=86307
I just realized that, even if PyWndProc_Call handles
WM_NCDESTROY, there is still likely to be a deadlock. In
that case, _celp.acquire (and thus PyGILState_Ensure) will
be called twice, first by the constructor and second by the
explicit call. The second call will overwrite _celp.state with
PyGILState_LOCKED. When _celp's destructor is called,
PyGILState_Release will not try to release the GIL even if the
first call to PyGILState_Ensure returned
PyGILState_UNLOCKED.
If I understand correctly, CEnterLeavePython.acquire should
probably look like:
void acquire(void) {
if (released) {
state = PyGILState_Ensure();
released = FALSE;
}
}
// also need:
CEnterLeavePython() {
released = TRUE;
acquire();
}
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=551954&aid=906305&group_id=78018
|