Bug 896896. Use MsgWaitForMultipleObjectsEx instead of WaitMessage. r=roc

This commit is contained in:
Nicholas Cameron 2013-07-31 08:51:45 +12:00
parent b0a17db4e6
commit 54b52aea3f
3 changed files with 36 additions and 1 deletions

View File

@ -270,6 +270,28 @@ WinUtils::GetMessage(LPMSG aMsg, HWND aWnd, UINT aFirstMessage,
return ::GetMessageW(aMsg, aWnd, aFirstMessage, aLastMessage);
}
/* static */
void
WinUtils::WaitForMessage()
{
DWORD result = ::MsgWaitForMultipleObjectsEx(0, NULL, INFINITE, QS_ALLINPUT,
MWMO_INPUTAVAILABLE);
NS_WARN_IF_FALSE(result != WAIT_FAILED, "Wait failed");
// This idiom is taken from the Chromium ipc code, see
// ipc/chromium/src/base/message+puimp_win.cpp:270.
// The intent is to avoid a busy wait when MsgWaitForMultipleObjectsEx
// returns quickly but PeekMessage would not return a message.
if (result == WAIT_OBJECT_0) {
MSG msg = {0};
DWORD queue_status = ::GetQueueStatus(QS_MOUSE);
if (HIWORD(queue_status) & QS_MOUSE &&
!PeekMessage(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE)) {
::WaitMessage();
}
}
}
/* static */
bool
WinUtils::GetRegistryKey(HKEY aRoot,

View File

@ -95,6 +95,19 @@ public:
UINT aLastMessage, UINT aOption);
static bool GetMessage(LPMSG aMsg, HWND aWnd, UINT aFirstMessage,
UINT aLastMessage);
/**
* Wait until a message is ready to be processed.
* Prefer using this method to directly calling ::WaitMessage since
* ::WaitMessage will wait if there is an unread message in the queue.
* That can cause freezes until another message enters the queue if the
* message is marked read by a call to PeekMessage which the caller is
* not aware of (e.g., from a different thread).
* Note that this method may cause sync dispatch of sent (as opposed to
* posted) messages.
*/
static void WaitForMessage();
/**
* Gets the value of a string-typed registry value.
*

View File

@ -308,7 +308,7 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
mozilla::HangMonitor::Suspend();
{
GeckoProfilerSleepRAII profiler_sleep;
::WaitMessage();
WinUtils::WaitForMessage();
}
}
} while (!gotMessage && mayWait);