summaryrefslogtreecommitdiffstats
path: root/Source/WebKit2/Platform/win/RunLoopWin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/Platform/win/RunLoopWin.cpp')
-rw-r--r--Source/WebKit2/Platform/win/RunLoopWin.cpp46
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);