WebKit Bugzilla
Attachment 342536 Details for
Bug 186455
: [Win] Remove RunLoopWin and WorkQueueWin
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-186455-20180613001211.patch (text/plain), 34.02 KB, created by
Yusuke Suzuki
on 2018-06-12 08:12:12 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Yusuke Suzuki
Created:
2018-06-12 08:12:12 PDT
Size:
34.02 KB
patch
obsolete
>Subversion Revision: 232750 >diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog >index c2c83cfbe4108647f6a4147c6c78e57d3c82fad0..d32cffa46cbe2835a045b3a1465e5a1221dcb70c 100644 >--- a/Source/WTF/ChangeLog >+++ b/Source/WTF/ChangeLog >@@ -1,3 +1,36 @@ >+2018-06-12 Yusuke Suzuki <utatane.tea@gmail.com> >+ >+ [Win] Remove RunLoopWin and WorkQueueWin >+ https://bugs.webkit.org/show_bug.cgi?id=186455 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ We sometimes want to integrate our WTF::RunLoop into the existing platform RunLoop >+ which is driven by the system or main function of the applications. For example, >+ RunLoopCF uses CFRunLoopGetCurrent() to use the *current* RunLoop which is used by >+ the application too. And RunLoopGLib is the same: It uses the glib *default* RunLoop >+ for the current application. >+ >+ On the other hand, Windows RunLoop implementation is different. It creates a special >+ window handle per RunLoop by CreateWindow. And we use the message loop of this >+ window handle. But this window handle is not shared by the application. This window >+ handle is only used by RunLoop. We do not have the way to post a message to this >+ window handle without interacting with this RunLoopWin. >+ >+ So, essentially, we do not need this RunLoopWin. This patch uses RunLoopGeneric and >+ WorkQueueGeneric in Windows. And remove WorkItemContext too since WorkItemContext >+ is not essentially related to Windows WorkQueue. >+ >+ * wtf/Platform.h: >+ * wtf/PlatformWin.cmake: >+ * wtf/RunLoop.h: >+ * wtf/WorkQueue.cpp: >+ * wtf/WorkQueue.h: >+ * wtf/win/RunLoopWin.cpp: Removed. >+ * wtf/win/WorkItemContext.cpp: Removed. >+ * wtf/win/WorkItemContext.h: Removed. >+ * wtf/win/WorkQueueWin.cpp: Removed. >+ > 2018-06-11 Saam Barati <sbarati@apple.com> > > The NaturalLoops algorithm only works when the list of blocks in a loop is de-duplicated >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 517b87c29b3dd61271bfcf3ef1e959a2518a551d..8e605da12eb9fd28a8a4aba05241a4d0bd029465 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,18 @@ >+2018-06-12 Yusuke Suzuki <utatane.tea@gmail.com> >+ >+ [Win] Remove RunLoopWin and WorkQueueWin >+ https://bugs.webkit.org/show_bug.cgi?id=186455 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ We use Windows RegisterWaitForSingleObject and UnregisterWaitEx here. >+ These functions are not inherently related to WorkQueue. >+ >+ * Platform/IPC/Connection.h: >+ * Platform/IPC/win/ConnectionWin.cpp: >+ (IPC::Connection::platformInvalidate): >+ (IPC::Connection::open): >+ > 2018-06-11 Carlos Garcia Campos <cgarcia@igalia.com> > > Unreviewed. Update OptionsGTK.cmake and NEWS for 2.21.4 release. >diff --git a/Source/WTF/wtf/Platform.h b/Source/WTF/wtf/Platform.h >index 02817717daeb7098577fc65c35e3df20a522ff60..793a4cc527bedbeef5b958d741cce361b6698e41 100644 >--- a/Source/WTF/wtf/Platform.h >+++ b/Source/WTF/wtf/Platform.h >@@ -1266,13 +1266,12 @@ > /* Use GLib's event loop abstraction. Primarily GTK port uses it. */ > #define USE_GLIB_EVENT_LOOP 1 > #elif OS(WINDOWS) >-/* Use Windows message pump abstraction. >- * Even if the port is AppleWin, we use the Windows message pump system for the event loop, >- * so that USE(WINDOWS_EVENT_LOOP) && USE(CF) can be true. >+/* Use the generic event loop implementation in Windows even if the port is AppleWin. >+ * So that USE(GENERIC_EVENT_LOOP) && USE(CF) can be true. > * And PLATFORM(WIN) and PLATFORM(GTK) are exclusive. If the port is GTK, > * PLATFORM(WIN) should be false. And in that case, GLib's event loop is used. > */ >-#define USE_WINDOWS_EVENT_LOOP 1 >+#define USE_GENERIC_EVENT_LOOP 1 > #elif PLATFORM(COCOA) > /* OS X and IOS. Use CoreFoundation & GCD abstraction. */ > #define USE_COCOA_EVENT_LOOP 1 >diff --git a/Source/WTF/wtf/PlatformWin.cmake b/Source/WTF/wtf/PlatformWin.cmake >index 014d7391d29f28a7559fb8de52531b87b037e7c6..1ccfbc76b4b20650296555e6bf1cbed4d23bcb67 100644 >--- a/Source/WTF/wtf/PlatformWin.cmake >+++ b/Source/WTF/wtf/PlatformWin.cmake >@@ -4,10 +4,12 @@ list(APPEND WTF_PUBLIC_HEADERS > win/GDIObject.h > win/SoftLinking.h > win/Win32Handle.h >- win/WorkItemContext.h > ) > > list(APPEND WTF_SOURCES >+ generic/RunLoopGeneric.cpp >+ generic/WorkQueueGeneric.cpp >+ > text/win/TextBreakIteratorInternalICUWin.cpp > > win/CPUTimeWin.cpp >@@ -15,9 +17,6 @@ list(APPEND WTF_SOURCES > win/MainThreadWin.cpp > win/MemoryFootprintWin.cpp > win/MemoryPressureHandlerWin.cpp >- win/RunLoopWin.cpp >- win/WorkItemContext.cpp >- win/WorkQueueWin.cpp > ) > > if (USE_CF) >diff --git a/Source/WTF/wtf/RunLoop.h b/Source/WTF/wtf/RunLoop.h >index f4fd3bf0432e6b2d1b30c7c28d993396cfe1aa43..f94cad92285305e5cddefbc71ccf5b7296011ac8 100644 >--- a/Source/WTF/wtf/RunLoop.h >+++ b/Source/WTF/wtf/RunLoop.h >@@ -108,14 +108,7 @@ class RunLoop : public FunctionDispatcher { > > Ref<RunLoop> m_runLoop; > >-#if USE(WINDOWS_EVENT_LOOP) >- bool isActive(const AbstractLocker&) const; >- static void timerFired(RunLoop*, uint64_t ID); >- uint64_t m_ID; >- MonotonicTime m_nextFireDate; >- Seconds m_interval; >- bool m_isRepeating; >-#elif USE(COCOA_EVENT_LOOP) >+#if USE(COCOA_EVENT_LOOP) > static void timerFired(CFRunLoopTimerRef, void*); > RetainPtr<CFRunLoopTimerRef> m_timer; > #elif USE(GLIB_EVENT_LOOP) >@@ -161,16 +154,7 @@ class RunLoop : public FunctionDispatcher { > Lock m_functionQueueLock; > Deque<Function<void()>> m_functionQueue; > >-#if USE(WINDOWS_EVENT_LOOP) >- static bool registerRunLoopMessageWindowClass(); >- static LRESULT CALLBACK RunLoopWndProc(HWND, UINT, WPARAM, LPARAM); >- LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); >- HWND m_runLoopMessageWindow; >- >- typedef HashMap<uint64_t, TimerBase*> TimerMap; >- Lock m_activeTimersLock; >- TimerMap m_activeTimers; >-#elif USE(COCOA_EVENT_LOOP) >+#if USE(COCOA_EVENT_LOOP) > static void performWork(void*); > RetainPtr<CFRunLoopRef> m_runLoop; > RetainPtr<CFRunLoopSourceRef> m_runLoopSource; >diff --git a/Source/WTF/wtf/WorkQueue.cpp b/Source/WTF/wtf/WorkQueue.cpp >index 063d72c2c75b9e363a223e4cfd7177996fbb9d2a..248db0886cd8315231240f0151d355b5088d2ca9 100644 >--- a/Source/WTF/wtf/WorkQueue.cpp >+++ b/Source/WTF/wtf/WorkQueue.cpp >@@ -38,10 +38,6 @@ > #include <wtf/Threading.h> > #include <wtf/text/WTFString.h> > >-#if USE(WINDOWS_EVENT_LOOP) >-#include <wtf/win/WorkItemContext.h> >-#endif >- > namespace WTF { > > Ref<WorkQueue> WorkQueue::create(const char* name, Type type, QOS qos) >diff --git a/Source/WTF/wtf/WorkQueue.h b/Source/WTF/wtf/WorkQueue.h >index 85eca62c0ca64002a19b2f11855ed0426e60ba1f..aea4405e3f7303a43db307a6fba578fcceaa85dc 100644 >--- a/Source/WTF/wtf/WorkQueue.h >+++ b/Source/WTF/wtf/WorkQueue.h >@@ -37,12 +37,6 @@ > #include <dispatch/dispatch.h> > #endif > >-#if USE(WINDOWS_EVENT_LOOP) >-#include <wtf/HashMap.h> >-#include <wtf/ThreadingPrimitives.h> >-#include <wtf/Vector.h> >-#endif >- > #if USE(GLIB_EVENT_LOOP) || USE(GENERIC_EVENT_LOOP) > #include <wtf/Condition.h> > #include <wtf/RunLoop.h> >@@ -50,10 +44,6 @@ > > namespace WTF { > >-#if USE(WINDOWS_EVENT_LOOP) >-class WorkItemContext; >-#endif >- > class WorkQueue final : public FunctionDispatcher { > > public: >@@ -81,9 +71,6 @@ class WorkQueue final : public FunctionDispatcher { > dispatch_queue_t dispatchQueue() const { return m_dispatchQueue; } > #elif USE(GLIB_EVENT_LOOP) || USE(GENERIC_EVENT_LOOP) > RunLoop& runLoop() const { return *m_runLoop; } >-#elif USE(WINDOWS_EVENT_LOOP) >- WTF_EXPORT_PRIVATE void registerHandle(HANDLE, Function<void()>&&); >- WTF_EXPORT_PRIVATE void unregisterAndCloseHandle(HANDLE); > #endif > > private: >@@ -92,31 +79,9 @@ class WorkQueue final : public FunctionDispatcher { > void platformInitialize(const char* name, Type, QOS); > void platformInvalidate(); > >-#if USE(WINDOWS_EVENT_LOOP) >- static void CALLBACK handleCallback(void* context, BOOLEAN timerOrWaitFired); >- static void CALLBACK timerCallback(void* context, BOOLEAN timerOrWaitFired); >- static DWORD WINAPI workThreadCallback(void* context); >- >- bool tryRegisterAsWorkThread(); >- void unregisterAsWorkThread(); >- void performWorkOnRegisteredWorkThread(); >- >- static void unregisterWaitAndDestroyItemSoon(Ref<WorkItemContext>&&); >- static DWORD WINAPI unregisterWaitAndDestroyItemCallback(void* context); >-#endif >- > #if USE(COCOA_EVENT_LOOP) > static void executeFunction(void*); > dispatch_queue_t m_dispatchQueue; >-#elif USE(WINDOWS_EVENT_LOOP) >- volatile LONG m_isWorkThreadRegistered; >- >- Lock m_functionQueueLock; >- Lock m_itemsMapLock; >- Vector<Function<void()>> m_functionQueue; >- HashMap<HANDLE, Ref<WorkItemContext>> m_itemsMap; >- >- HANDLE m_timerQueue; > #elif USE(GLIB_EVENT_LOOP) || USE(GENERIC_EVENT_LOOP) > RunLoop* m_runLoop; > #endif >diff --git a/Source/WTF/wtf/win/RunLoopWin.cpp b/Source/WTF/wtf/win/RunLoopWin.cpp >deleted file mode 100644 >index 368132abd27b739135c77413a635e27e7190db60..0000000000000000000000000000000000000000 >--- a/Source/WTF/wtf/win/RunLoopWin.cpp >+++ /dev/null >@@ -1,199 +0,0 @@ >-/* >- * Copyright (C) 2010 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >- * THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "RunLoop.h" >- >-#include <wtf/WindowsExtras.h> >- >-namespace WTF { >- >-static const UINT PerformWorkMessage = WM_USER + 1; >-static const LPWSTR kRunLoopMessageWindowClassName = L"RunLoopMessageWindow"; >- >-LRESULT CALLBACK RunLoop::RunLoopWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) >-{ >- if (RunLoop* runLoop = static_cast<RunLoop*>(getWindowPointer(hWnd, 0))) >- return runLoop->wndProc(hWnd, message, wParam, lParam); >- >- if (message == WM_CREATE) { >- LPCREATESTRUCT createStruct = reinterpret_cast<LPCREATESTRUCT>(lParam); >- >- // Associate the RunLoop with the window. >- setWindowPointer(hWnd, 0, createStruct->lpCreateParams); >- return 0; >- } >- >- return ::DefWindowProc(hWnd, message, wParam, lParam); >-} >- >-LRESULT RunLoop::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) >-{ >- switch (message) { >- case PerformWorkMessage: >- performWork(); >- return 0; >- case WM_TIMER: >- RunLoop::TimerBase::timerFired(this, wParam); >- return 0; >- } >- >- return ::DefWindowProc(hWnd, message, wParam, lParam); >-} >- >-void RunLoop::run() >-{ >- MSG message; >- while (BOOL result = ::GetMessage(&message, 0, 0, 0)) { >- if (result == -1) >- break; >- ::TranslateMessage(&message); >- ::DispatchMessage(&message); >- } >-} >- >-void RunLoop::stop() >-{ >- ::PostQuitMessage(0); >-} >- >-bool RunLoop::registerRunLoopMessageWindowClass() >-{ >- // FIXME: This really only needs to be called once. >- >- WNDCLASS windowClass = { 0 }; >- windowClass.lpfnWndProc = RunLoop::RunLoopWndProc; >- windowClass.cbWndExtra = sizeof(RunLoop*); >- windowClass.lpszClassName = kRunLoopMessageWindowClassName; >- >- return !!::RegisterClass(&windowClass); >-} >- >-RunLoop::RunLoop() >-{ >- registerRunLoopMessageWindowClass(); >- >- m_runLoopMessageWindow = ::CreateWindow(kRunLoopMessageWindowClassName, 0, 0, >- CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, 0, this); >- ASSERT(::IsWindow(m_runLoopMessageWindow)); >-} >- >-RunLoop::~RunLoop() >-{ >- // FIXME: Tear down the work item queue here. >-} >- >-void RunLoop::wakeUp() >-{ >- // FIXME: No need to wake up the run loop if we've already called dispatch >- // before the run loop has had the time to respond. >- ::PostMessage(m_runLoopMessageWindow, PerformWorkMessage, reinterpret_cast<WPARAM>(this), 0); >-} >- >-// RunLoop::Timer >- >-void RunLoop::TimerBase::timerFired(RunLoop* runLoop, uint64_t ID) >-{ >- TimerBase* timer = nullptr; >- { >- LockHolder locker(runLoop->m_activeTimersLock); >- TimerMap::iterator it = runLoop->m_activeTimers.find(ID); >- if (it == runLoop->m_activeTimers.end()) { >- // The timer must have been stopped after the WM_TIMER message was posted to the message queue. >- return; >- } >- >- timer = it->value; >- >- if (!timer->m_isRepeating) { >- runLoop->m_activeTimers.remove(it); >- ::KillTimer(runLoop->m_runLoopMessageWindow, ID); >- } else >- timer->m_nextFireDate = MonotonicTime::now() + timer->m_interval; >- } >- >- timer->fired(); >-} >- >-static uint64_t generateTimerID() >-{ >- static uint64_t uniqueTimerID = 1; >- return uniqueTimerID++; >-} >- >-RunLoop::TimerBase::TimerBase(RunLoop& runLoop) >- : m_runLoop(runLoop) >- , m_ID(generateTimerID()) >- , m_isRepeating(false) >-{ >-} >- >-RunLoop::TimerBase::~TimerBase() >-{ >- stop(); >-} >- >-void RunLoop::TimerBase::start(Seconds nextFireInterval, bool repeat) >-{ >- LockHolder locker(m_runLoop->m_activeTimersLock); >- m_isRepeating = repeat; >- m_runLoop->m_activeTimers.set(m_ID, this); >- m_interval = nextFireInterval; >- m_nextFireDate = MonotonicTime::now() + m_interval; >- ::SetTimer(m_runLoop->m_runLoopMessageWindow, m_ID, nextFireInterval.millisecondsAs<unsigned>(), 0); >-} >- >-void RunLoop::TimerBase::stop() >-{ >- LockHolder locker(m_runLoop->m_activeTimersLock); >- TimerMap::iterator it = m_runLoop->m_activeTimers.find(m_ID); >- if (it == m_runLoop->m_activeTimers.end()) >- return; >- >- m_runLoop->m_activeTimers.remove(it); >- ::KillTimer(m_runLoop->m_runLoopMessageWindow, m_ID); >-} >- >-bool RunLoop::TimerBase::isActive(const AbstractLocker&) const >-{ >- return m_runLoop->m_activeTimers.contains(m_ID); >-} >- >-bool RunLoop::TimerBase::isActive() const >-{ >- LockHolder locker(m_runLoop->m_activeTimersLock); >- return isActive(locker); >-} >- >-Seconds RunLoop::TimerBase::secondsUntilFire() const >-{ >- LockHolder locker(m_runLoop->m_activeTimersLock); >- if (isActive(locker)) >- return std::max<Seconds>(m_nextFireDate - MonotonicTime::now(), 0_s); >- return 0_s; >-} >- >- >-} // namespace WTF >diff --git a/Source/WTF/wtf/win/WorkItemContext.cpp b/Source/WTF/wtf/win/WorkItemContext.cpp >deleted file mode 100755 >index 9ec11a9d322dd18c02f18f8bf7f89c33aa058b0f..0000000000000000000000000000000000000000 >--- a/Source/WTF/wtf/win/WorkItemContext.cpp >+++ /dev/null >@@ -1,53 +0,0 @@ >-/* >- * Copyright (C) 2010, 2015 Apple Inc. All rights reserved. >- * Copyright (C) 2017 Sony Interactive Entertainment Inc. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >- * THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "WorkItemContext.h" >- >-#include <Windows.h> >-#include <wtf/Threading.h> >-#include <wtf/WorkQueue.h> >- >-namespace WTF { >- >-WorkItemContext::WorkItemContext(HANDLE handle, HANDLE waitHandle, Function<void()>&& function, WorkQueue* queue) >- : m_handle(handle) >- , m_waitHandle(waitHandle) >- , m_function(WTFMove(function)) >- , m_queue(queue) >-{ >-} >- >-Ref<WorkItemContext> WorkItemContext::create(HANDLE handle, HANDLE waitHandle, Function<void()>&& function, WorkQueue* queue) >-{ >- return adoptRef(*new WorkItemContext(handle, waitHandle, WTFMove(function), queue)); >-} >- >-WorkItemContext::~WorkItemContext() >-{ >-} >- >-} // namespace WTF >diff --git a/Source/WTF/wtf/win/WorkItemContext.h b/Source/WTF/wtf/win/WorkItemContext.h >deleted file mode 100644 >index 0aa15c75269c468d014cf7d0a720c38b4369df8e..0000000000000000000000000000000000000000 >--- a/Source/WTF/wtf/win/WorkItemContext.h >+++ /dev/null >@@ -1,61 +0,0 @@ >-/* >- * Copyright (C) 2010, 2015 Apple Inc. All rights reserved. >- * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. >- * Copyright (C) 2017 Sony Interactive Entertainment Inc. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >- * THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#pragma once >- >-#include <Windows.h> >-#include <functional> >-#include <wtf/FunctionDispatcher.h> >-#include <wtf/RefPtr.h> >-#include <wtf/ThreadSafeRefCounted.h> >-#include <wtf/win/Win32Handle.h> >- >-namespace WTF { >- >-class WorkQueue; >- >-class WorkItemContext : public ThreadSafeRefCounted<WorkItemContext> { >- >-public: >- static Ref<WorkItemContext> create(HANDLE, HANDLE, Function<void()>&&, WorkQueue*); >- virtual ~WorkItemContext(); >- >- Win32Handle& handle() { return m_handle; } >- Win32Handle& waitHandle() { return m_waitHandle; } >- Function<void()>& function() { return m_function; } >- WorkQueue* queue() const { return m_queue.get(); } >- >-private: >- WorkItemContext(HANDLE, HANDLE, Function<void()>&&, WorkQueue*); >- >- Win32Handle m_handle; >- Win32Handle m_waitHandle; >- Function<void()> m_function; >- RefPtr<WorkQueue> m_queue; >-}; >- >-} >diff --git a/Source/WTF/wtf/win/WorkQueueWin.cpp b/Source/WTF/wtf/win/WorkQueueWin.cpp >deleted file mode 100644 >index 41bfde096d7cb1e262dfc9e782501b17b7e0dd77..0000000000000000000000000000000000000000 >--- a/Source/WTF/wtf/win/WorkQueueWin.cpp >+++ /dev/null >@@ -1,247 +0,0 @@ >-/* >- * Copyright (C) 2010-2018 Apple Inc. All rights reserved. >- * Copyright (C) 2017 Sony Interactive Entertainment Inc. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >- * THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "WorkQueue.h" >- >-#include <wtf/MathExtras.h> >-#include <wtf/Threading.h> >-#include <wtf/win/WorkItemContext.h> >- >-namespace WTF { >- >-void WorkQueue::handleCallback(void* data, BOOLEAN timerOrWaitFired) >-{ >- ASSERT_ARG(data, data); >- ASSERT_ARG(timerOrWaitFired, !timerOrWaitFired); >- >- WorkItemContext* context = static_cast<WorkItemContext*>(data); >- WorkQueue* queue = context->queue(); >- >- RefPtr<WorkItemContext> protector(context); >- queue->dispatch([protector] { >- protector->function()(); >- }); >-} >- >-void WorkQueue::registerHandle(HANDLE handle, Function<void()>&& function) >-{ >- Ref<WorkItemContext> context = WorkItemContext::create(handle, nullptr, WTFMove(function), this); >- >- if (!::RegisterWaitForSingleObject(&context->waitHandle().m_handle, handle, handleCallback, context.ptr(), INFINITE, WT_EXECUTEDEFAULT)) >- ASSERT_WITH_MESSAGE(m_timerQueue, "::RegisterWaitForSingleObject %lu", ::GetLastError()); >- >- auto locker = holdLock(m_itemsMapLock); >- ASSERT_ARG(handle, !m_itemsMap.contains(handle)); >- m_itemsMap.set(handle, WTFMove(context)); >-} >- >-void WorkQueue::unregisterAndCloseHandle(HANDLE handle) >-{ >- auto locker = holdLock(m_itemsMapLock); >- ASSERT_ARG(handle, m_itemsMap.contains(handle)); >- >- unregisterWaitAndDestroyItemSoon(m_itemsMap.take(handle).value()); >-} >- >-DWORD WorkQueue::workThreadCallback(void* context) >-{ >- ASSERT_ARG(context, context); >- >- WorkQueue* queue = static_cast<WorkQueue*>(context); >- >- if (queue->tryRegisterAsWorkThread()) >- queue->performWorkOnRegisteredWorkThread(); >- >- queue->deref(); >- >- return 0; >-} >- >-void WorkQueue::performWorkOnRegisteredWorkThread() >-{ >- ASSERT(m_isWorkThreadRegistered); >- >- m_functionQueueLock.lock(); >- >- while (!m_functionQueue.isEmpty()) { >- Vector<Function<void()>> functionQueue; >- m_functionQueue.swap(functionQueue); >- >- // Allow more work to be scheduled while we're not using the queue directly. >- m_functionQueueLock.unlock(); >- for (auto& function : functionQueue) >- function(); >- m_functionQueueLock.lock(); >- } >- >- // One invariant we maintain is that any work scheduled while a work thread is registered will >- // be handled by that work thread. Unregister as the work thread while the queue lock is still >- // held so that no work can be scheduled while we're still registered. >- unregisterAsWorkThread(); >- >- m_functionQueueLock.unlock(); >-} >- >-void WorkQueue::platformInitialize(const char* name, Type, QOS) >-{ >- m_isWorkThreadRegistered = 0; >- m_timerQueue = ::CreateTimerQueue(); >- ASSERT_WITH_MESSAGE(m_timerQueue, "::CreateTimerQueue failed with error %lu", ::GetLastError()); >-} >- >-bool WorkQueue::tryRegisterAsWorkThread() >-{ >- LONG result = ::InterlockedCompareExchange(&m_isWorkThreadRegistered, 1, 0); >- ASSERT(!result || result == 1); >- return !result; >-} >- >-void WorkQueue::unregisterAsWorkThread() >-{ >- LONG result = ::InterlockedCompareExchange(&m_isWorkThreadRegistered, 0, 1); >- ASSERT_UNUSED(result, result == 1); >-} >- >-void WorkQueue::platformInvalidate() >-{ >- // FIXME: We need to ensure that any timer-queue timers that fire after this point don't try to >- // access this WorkQueue <http://webkit.org/b/44690>. >- ::DeleteTimerQueueEx(m_timerQueue, 0); >-} >- >-void WorkQueue::dispatch(Function<void()>&& function) >-{ >- auto locker = holdLock(m_functionQueueLock); >- m_functionQueue.append(WTFMove(function)); >- >- // Spawn a work thread to perform the work we just added. As an optimization, we avoid >- // spawning the thread if a work thread is already registered. This prevents multiple work >- // threads from being spawned in most cases. (Note that when a work thread has been spawned but >- // hasn't registered itself yet, m_isWorkThreadRegistered will be false and we'll end up >- // spawning a second work thread here. But work thread registration process will ensure that >- // only one thread actually ends up performing work.) >- if (!m_isWorkThreadRegistered) { >- ref(); >- ::QueueUserWorkItem(workThreadCallback, this, WT_EXECUTEDEFAULT); >- } >-} >- >-struct TimerContext : public ThreadSafeRefCounted<TimerContext> { >- static RefPtr<TimerContext> create() { return adoptRef(new TimerContext); } >- >- Lock timerLock; >- WorkQueue* queue { nullptr }; >- HANDLE timer { nullptr }; >- Function<void()> function; >- >-private: >- TimerContext() = default; >-}; >- >-void WorkQueue::timerCallback(void* context, BOOLEAN timerOrWaitFired) >-{ >- ASSERT_ARG(context, context); >- ASSERT_UNUSED(timerOrWaitFired, timerOrWaitFired); >- >- // Balanced by leakRef in scheduleWorkAfterDelay. >- RefPtr<TimerContext> timerContext = adoptRef(static_cast<TimerContext*>(context)); >- >- timerContext->queue->dispatch(WTFMove(timerContext->function)); >- >- auto locker = holdLock(timerContext->timerLock); >- ASSERT(timerContext->timer); >- ASSERT(timerContext->queue->m_timerQueue); >- if (!::DeleteTimerQueueTimer(timerContext->queue->m_timerQueue, timerContext->timer, 0)) { >- // Getting ERROR_IO_PENDING here means that the timer will be destroyed once the callback is done executing. >- ASSERT_WITH_MESSAGE(::GetLastError() == ERROR_IO_PENDING, "::DeleteTimerQueueTimer failed with error %lu", ::GetLastError()); >- } >-} >- >-void WorkQueue::dispatchAfter(Seconds duration, Function<void()>&& function) >-{ >- ASSERT(m_timerQueue); >- ref(); >- >- RefPtr<TimerContext> context = TimerContext::create(); >- context->queue = this; >- context->function = WTFMove(function); >- >- { >- // The timer callback could fire before ::CreateTimerQueueTimer even returns, so we protect >- // context->timer with a mutex to ensure the timer callback doesn't access it before the >- // timer handle has been stored in it. >- auto locker = holdLock(context->timerLock); >- >- int64_t milliseconds = duration.milliseconds(); >- >- // From empirical testing, we've seen CreateTimerQueueTimer() sometimes fire up to 5+ ms early. >- // This causes havoc for clients of this code that expect to not be called back until the >- // specified duration has expired. Other folks online have also observed some slop in the >- // firing times of CreateTimerQuqueTimer(). From the data posted at >- // http://omeg.pl/blog/2011/11/on-winapi-timers-and-their-resolution, it appears that the slop >- // can be up to about 10 ms. To ensure that we don't fire the timer early, we'll tack on a >- // slop adjustment to the duration, and we'll use double the worst amount of slop observed >- // so far. >- const int64_t slopAdjustment = 20; >- if (milliseconds) >- milliseconds += slopAdjustment; >- >- // Since our timer callback is quick, we can execute in the timer thread itself and avoid >- // an extra thread switch over to a worker thread. >- if (!::CreateTimerQueueTimer(&context->timer, m_timerQueue, timerCallback, context.get(), clampTo<DWORD>(milliseconds), 0, WT_EXECUTEINTIMERTHREAD)) { >- ASSERT_WITH_MESSAGE(false, "::CreateTimerQueueTimer failed with error %lu", ::GetLastError()); >- return; >- } >- } >- >- // The timer callback will handle destroying context. >- context.leakRef(); >-} >- >-void WorkQueue::unregisterWaitAndDestroyItemSoon(Ref<WorkItemContext>&& workItem) >-{ >- // We're going to make a blocking call to ::UnregisterWaitEx before closing the handle. (The >- // blocking version of ::UnregisterWaitEx is much simpler than the non-blocking version.) If we >- // do this on the current thread, we'll deadlock if we're currently in a callback function for >- // the wait we're unregistering. So instead we do it asynchronously on some other worker thread. >- ::QueueUserWorkItem(unregisterWaitAndDestroyItemCallback, workItem.ptr(), WT_EXECUTEDEFAULT); >-} >- >-DWORD WINAPI WorkQueue::unregisterWaitAndDestroyItemCallback(void* data) >-{ >- ASSERT_ARG(data, data); >- WorkItemContext* context = static_cast<WorkItemContext*>(data); >- >- // Now that we know we're not in a callback function for the wait we're unregistering, we can >- // make a blocking call to ::UnregisterWaitEx. >- if (!::UnregisterWaitEx(context->waitHandle().get(), INVALID_HANDLE_VALUE)) >- ASSERT_WITH_MESSAGE(false, "::UnregisterWaitEx failed with '%s'", ::GetLastError()); >- >- return 0; >-} >- >-} // namespace WTF >diff --git a/Source/WebKit/Platform/IPC/Connection.h b/Source/WebKit/Platform/IPC/Connection.h >index 8c380b3f9ed13e75056fa26c2453659d995536ab..33e8266cf2b6f8ccea0b067de94ad86c2c12b606 100644 >--- a/Source/WebKit/Platform/IPC/Connection.h >+++ b/Source/WebKit/Platform/IPC/Connection.h >@@ -346,8 +346,10 @@ class Connection : public ThreadSafeRefCounted<Connection> { > > Vector<uint8_t> m_readBuffer; > OVERLAPPED m_readState; >+ HANDLE m_readerWaitHandle; > std::unique_ptr<Encoder> m_pendingWriteEncoder; > OVERLAPPED m_writeState; >+ HANDLE m_writerWaitHandle; > HANDLE m_connectionPipe; > #endif > }; >diff --git a/Source/WebKit/Platform/IPC/win/ConnectionWin.cpp b/Source/WebKit/Platform/IPC/win/ConnectionWin.cpp >index bc94c67d11804000fda6bee930fa84597f4a334c..92e6dbfc43d34bdee5c5df6ba00d26b108952d2d 100644 >--- a/Source/WebKit/Platform/IPC/win/ConnectionWin.cpp >+++ b/Source/WebKit/Platform/IPC/win/ConnectionWin.cpp >@@ -88,10 +88,21 @@ void Connection::platformInvalidate() > > m_isConnected = false; > >- m_connectionQueue->unregisterAndCloseHandle(m_readState.hEvent); >+ // We call ::UnregisterWaitEx directly here. Since ::UnregisterWaitEx drains all the remaining tasks here, >+ // it would cause deadlock if this function itself is executed in Windows callback functions. But this call >+ // is safe since our callbacks immediately dispatch a task to WorkQueue. And no Windows callbacks call this >+ // Connection::platformInvalidate. >+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms685061(v=vs.85).aspx >+ // >+ // And do not ::CloseHandle(waitHandle). >+ // > Note that a wait handle cannot be used in functions that require an object handle, such as CloseHandle. >+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms685061(v=vs.85).aspx >+ ::UnregisterWaitEx(m_readerWaitHandle, INVALID_HANDLE_VALUE); >+ ::CloseHandle(m_readState.hEvent); > m_readState.hEvent = 0; > >- m_connectionQueue->unregisterAndCloseHandle(m_writeState.hEvent); >+ ::UnregisterWaitEx(m_writerWaitHandle, INVALID_HANDLE_VALUE); >+ ::CloseHandle(m_writeState.hEvent); > m_writeState.hEvent = 0; > > ::CloseHandle(m_connectionPipe); >@@ -245,13 +256,32 @@ bool Connection::open() > RefPtr<Connection> protectedThis(this); > > // Start listening for read and write state events. >- m_connectionQueue->registerHandle(m_readState.hEvent, [protectedThis] { >- protectedThis->readEventHandler(); >- }); >- >- m_connectionQueue->registerHandle(m_writeState.hEvent, [protectedThis] { >- protectedThis->writeEventHandler(); >- }); >+ BOOL result; >+ result = ::RegisterWaitForSingleObject( >+ &m_readerWaitHandle, >+ m_readState.hEvent, >+ [] ((void* data, BOOLEAN timerOrWaitFired) { >+ ASSERT_UNUSED(timerOrWaitFired, !timerOrWaitFired); >+ // This is safe since we call ::UnregisterWaitEx directly when closing. >+ RefPtr<Connection> protectedThis(static_cast<Connection*>(data)); >+ protectedThis->m_connectionQueue->dispatch([protectedThis = WTFMove(protectedThis)] { >+ protectedThis->readEventHandler(); >+ }); >+ }, this, INFINITE, WT_EXECUTEDEFAULT)); >+ ASSERT(result); >+ >+ result = ::RegisterWaitForSingleObject( >+ &m_writerWaitHandle, >+ m_writeState.hEvent, >+ [] ((void* data, BOOLEAN timerOrWaitFired) { >+ ASSERT_UNUSED(timerOrWaitFired, !timerOrWaitFired); >+ // This is safe since we call ::UnregisterWaitEx directly when closing. >+ RefPtr<Connection> protectedThis(static_cast<Connection*>(data)); >+ protectedThis->m_connectionQueue->dispatch([protectedThis = WTFMove(protectedThis)] { >+ protectedThis->writeEventHandler(); >+ }); >+ }, this, INFINITE, WT_EXECUTEDEFAULT)); >+ ASSERT(result); > > // Schedule a read. > m_connectionQueue->dispatch([protectedThis] {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
ews-watchlist
:
commit-queue-
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 186455
: 342536 |
342569
|
342588