Fix handling of spurious wake ups in GetNextMessageTimeout() in wxMSW.

It didn't take long to realize that changes of r78041 did break something
(see #9053), as MsgWaitForMultipleObjects() can return indicating the message
availability even if no message is actually available in the queue. This
notably happens when the application is activated.

Fix this by calling MsgWaitForMultipleObjects() in a loop until we do get a
message. Notice that this only works correctly with the infinite timeout as we
don't update the remaining time to wait after a spurious wake-up, but this
shouldn't be a problem in practice as no such wake-ups should happen anyhow
during a small timeout duration -- and nobody typically uses long ones.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@78047 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2014-10-19 14:16:18 +00:00
parent a786c5094a
commit cf8700162d

View File

@ -102,10 +102,7 @@ int wxMSWEventLoopBase::GetNextMessageTimeout(WXMSG *msg, unsigned long timeout)
// MsgWaitForMultipleObjects() won't notice any input which was already
// examined (e.g. using PeekMessage()) but not yet removed from the queue
// so we need to remove any immediately messages manually
//
// NB: using MsgWaitForMultipleObjectsEx() could simplify the code here but
// it is not available in very old Windows versions
if ( !::PeekMessage(msg, 0, 0, 0, PM_REMOVE) )
while ( !::PeekMessage(msg, 0, 0, 0, PM_REMOVE) )
{
DWORD rc = ::MsgWaitForMultipleObjects
(
@ -131,17 +128,12 @@ int wxMSWEventLoopBase::GetNextMessageTimeout(WXMSG *msg, unsigned long timeout)
// return to the event loop, so pretend there was WM_NULL in
// the queue.
wxZeroMemory(*msg);
break;
return TRUE;
case WAIT_OBJECT_0 + 1:
// Some message is supposed to be available.
if ( !::PeekMessage(msg, 0, 0, 0, PM_REMOVE) )
{
// somehow it may happen that MsgWaitForMultipleObjects()
// returns true but there are no messages -- just treat it
// the same as timeout then
return -1;
}
// Some message is supposed to be available, but spurious
// wake ups are also possible, so just return to the loop:
// either we'll get the message or start waiting again.
break;
}
}