Hi,
hopefully somebody familiar with messaging can immediately spot what's wrong with the code below.
The winmm/midi tests currently in git, using PeekMsg, show that the messages (from CALLBACK_WINDOW) are almost always immediately available.
Yet the code below, based on MsgWaitFor... times out multiple times during each test run. Why? This seems to affect only the messages 3c9/3ca (MOM_DONE and MOM_CALLBACK).
"Bad wait 102 0": 0x102 is WAIT_TIMEOUT. That should never happen.
diff --git a/dlls/winmm/tests/midi.c b/dlls/winmm/tests/midi.c index 15e02e2..a23fa19 100644 --- a/dlls/winmm/tests/midi.c +++ b/dlls/winmm/tests/midi.c @@ -67,8 +67,27 @@ static void test_notification(HWND hwnd, const char* command, UINT m1, DWORD_PTR if (hwnd) { /* msg.wParam is hmidiout, msg.lParam is the mhdr (or 0) */ BOOL seen; +#if 0 do { seen = PeekMessageA(&msg, hwnd, 0, 0, PM_REMOVE); } while(seen && spurious_message(&msg)); +#else + seen=0; + if (m1 && !seen) { + /* We observe intermittent delayed notification. Perhaps + * the OS preempts the player thread after setting MHDR_DONE + * or clearing INQUEUE, before calling DriverCallback. */ + DWORD x; + trace("Waiting for delayed message %x from %s\n", m1, command); + SetLastError(0xDEADBEEF); +#if 0 + x=MsgWaitForMultipleObjects(0, NULL, FALSE, 9999, QS_POSTMESSAGE); +#else + x=MsgWaitForMultipleObjects(0, NULL, FALSE, /*INFINITE*/9999, QS_ALLINPUT); +#endif + ok(x==WAIT_OBJECT_0,"Bad wait %x %d\n",x, GetLastError()); + seen = PeekMessageA(&msg, hwnd, 0, 0, PM_REMOVE); + } +#endif if (seen) { trace("Message %x, wParam=%lx, lParam=%lx from %s\n", msg.message, msg.wParam, msg.lParam, command);
Thanks for your help, Jörg Höhle
Joerg-Cyril.Hoehle@t-systems.com writes:
hopefully somebody familiar with messaging can immediately spot what's wrong with the code below.
The winmm/midi tests currently in git, using PeekMsg, show that the messages (from CALLBACK_WINDOW) are almost always immediately available.
Yet the code below, based on MsgWaitFor... times out multiple times during each test run. Why?
Message waiting functions only return for new input. You need to make sure the queue is empty before waiting.
Hi,
Alexandre wrote:
Message waiting functions only return for new input. You need to make sure the queue is empty before waiting.
Actually, now that I believe I understand the issue, I'd rephrase it differently: The queue need not be empty (a message might have arrived 1 microsecond before the call to MsgWaitFor*). The key issue is that once you start to call PeekMessage or GetMessage, you must empty the queue with these functions before calling Wait again, because all messages present in the queue at Get/PeekMessage time will be marked "not new" (my understanding now of MSDN).
for(;;) { PeekMessage(REMOVE)/*=pick 1*/; Wait(); } will timeout/hang because of this when 2 messages arrive. Exactly that happened to my code.
Regards, Jörg Höhle