diff options
Diffstat (limited to 'Source/WebKit2/Platform/win/RunLoopWin.cpp')
-rw-r--r-- | Source/WebKit2/Platform/win/RunLoopWin.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/Source/WebKit2/Platform/win/RunLoopWin.cpp b/Source/WebKit2/Platform/win/RunLoopWin.cpp index 0ca7d9b..21bc2e0 100644 --- a/Source/WebKit2/Platform/win/RunLoopWin.cpp +++ b/Source/WebKit2/Platform/win/RunLoopWin.cpp @@ -26,7 +26,12 @@ #include "config.h" #include "RunLoop.h" +#include "BinarySemaphore.h" #include "WorkItem.h" +#include <wtf/CurrentTime.h> + +using namespace CoreIPC; +using namespace std; static const UINT PerformWorkMessage = WM_USER + 1; static const LPWSTR kRunLoopMessageWindowClassName = L"RunLoopMessageWindow"; @@ -74,6 +79,47 @@ void RunLoop::run() } } +bool RunLoop::dispatchSentMessagesUntil(const Vector<HWND>& windows, CoreIPC::BinarySemaphore& semaphore, double absoluteTime) +{ + if (windows.isEmpty()) + return semaphore.wait(absoluteTime); + + HANDLE handle = semaphore.event(); + DWORD handleCount = 1; + + while (true) { + DWORD interval = absoluteTimeToWaitTimeoutInterval(absoluteTime); + if (!interval) { + // Consider the wait to have timed out, even if the semaphore is currently signaled. + // This matches the WTF::ThreadCondition implementation of BinarySemaphore::wait. + return false; + } + + DWORD result = ::MsgWaitForMultipleObjectsEx(handleCount, &handle, interval, QS_SENDMESSAGE, 0); + if (result == WAIT_OBJECT_0) { + // The semaphore was signaled. + return true; + } + if (result == WAIT_TIMEOUT) { + // absoluteTime was reached. + return false; + } + if (result == WAIT_OBJECT_0 + handleCount) { + // One or more sent messages are available. Process sent messages for all the windows + // we were given, since we don't have a way of knowing which window has available sent + // messages. + for (size_t i = 0; i < windows.size(); ++i) { + MSG message; + ::PeekMessageW(&message, windows[i], 0, 0, PM_NOREMOVE | PM_QS_SENDMESSAGE); + } + continue; + } + ASSERT_WITH_MESSAGE(result != WAIT_FAILED, "::MsgWaitForMultipleObjectsEx failed with error %lu", ::GetLastError()); + ASSERT_WITH_MESSAGE(false, "::MsgWaitForMultipleObjectsEx returned unexpected result %lu", result); + return false; + } +} + void RunLoop::stop() { ::PostQuitMessage(0); |