I have a problem with a crash in a Windows (Win 2K) message loop
coded in a python extension module. I wonder if someone can
see something wrong with the code below.
The context is this: My Python program was originally coded using
wxWindows. It worked very well, but, after running for a full week or
more on my client's machines, their machine would crash with a
totally garbled display. All the common things were checked,
memory leaks, GDI object leaks, the display cards were changed,
and on and on. I ran the program on two of my own machines,
and it ran for more than two weeks without failure. My client
calls the shots, and he required that the app be re-written to
not use wxWindows. I thereupon coded a C extension module to
perform basic graphics and gui operations, and wrote a
Python module that implemented the subset of the wxWindows
interface that was used by my app, using this extension module.
This too "works". My Python program delivers essentially the
same appearance and behaviour using my interface and extension
module, as it did when it ran using wxWindows. However, there
are a couple of unresolved problems, and I am hoping to get
some help with one of them.
The app runs, and when I change desktops (I have a multiple-
desktop utility), a windows event occurs, and BEFORE it is
delivered by GetMessage, a crash (acces violation) occurs
inside of the GetMessage, which had bee blocked until this
(unknown) event occurs. The same crash also occurs if I
use the little applet to magnify the screen. That applet
reconfigures the desktop so that the "screen" is reduced
in size, leaving a band at the top of the screen that displays
the magnified pixels near the cursor. When the magnifier
does this reconfiguration of the desktop, an unknown event
occurs, and GetMessage crashes before it can return the
event to the message loop. Again I have checked for
GDI object leaks, memory leaks, reference counting errors
etc.
Although my app when fully functioning is multi-threading,
I removed all the threading code. No threads but the main
thread are running, so there are no deadlock or resource
races or other concurrent programming issues as far a I
know. However, the crash will not occur if the
Py_BEGIN_ALLOW_THREADS ... Py_END_ALLOW_THREADS
bracket is removed from around the GetMessage call.
Can anyone shed some light on what the problem here could be?
Thanks,
Parzival
---------------------------------------------------------------------------------------
static PyObject *MyWin_MessageLoop (PyObject *self, PyObject *args)
{
// Windows dispatch loop begins here.
MSG Message;
bool Quit = false;
for ( ; ; ) {
if (::PeekMessage(&Message, NULL, 0, 0, PM_NOREMOVE) == 0) {
Py_BEGIN_ALLOW_THREADS
// App crashes somewhere in GetMessage if Py_BEGIN_ALLOW_THREADS
// call above is executed. Does not crash if it and the matching
// Py_END_ALLOW_THREADS below are removed. No threads are
// instantiated or active.
Quit = GetMessage(&Message, NULL, NULL, NULL) == 0;
Py_END_ALLOW_THREADS
} else
Quit = GetMessage(&Message, NULL, NULL, NULL) == 0;
if (Quit) break;
if (Message.message == WM_USER + 1) {
InvalidateRect (_Window, NULL, TRUE);
UpdateWindow (_Window);
} else if (Message.message == WM_USER + 2) {
if ( _App ) {
PyObject* args = (PyObject*) Message.lParam;
PyObject* res = PyObject_CallMethod(_App, "OnEvent", "O", args);
Py_DECREF(args);
if ( res == NULL && PyErr_Occurred() )
PyErr_Print();
}
} else {
TranslateMessage (&Message);
DispatchMessage (&Message);
}
}