Diff
Modified: trunk/Source/WTF/ChangeLog (242693 => 242694)
--- trunk/Source/WTF/ChangeLog 2019-03-11 00:27:22 UTC (rev 242693)
+++ trunk/Source/WTF/ChangeLog 2019-03-11 02:36:23 UTC (rev 242694)
@@ -1,3 +1,39 @@
+2019-03-10 Yusuke Suzuki <[email protected]> and Fujii Hironori <[email protected]>
+
+ [WTF] Align assumption in RunLoopWin to the other platform's RunLoop
+ https://bugs.webkit.org/show_bug.cgi?id=181151
+
+ Reviewed by Don Olmstead.
+
+ This patch fixes RunLoop in Windows to align it to the implementations in the other platforms
+ to use RunLoop more aggressively.
+
+ * wtf/RunLoop.h:
+ (WTF::RunLoop::Timer::Timer):
+ * wtf/win/MainThreadWin.cpp:
+ (initializeMainThreadPlatform): Call RunLoop::registerRunLoopMessageWindowClass.
+ * wtf/win/RunLoopWin.cpp:
+ (WTF::RunLoop::wndProc):
+ (WTF::RunLoop::iterate):
+ (WTF::RunLoop::stop):
+ PostQuitMessage is only available in the RunLoop's thread. We should post a message and call
+ it inside this task.
+
+ (WTF::RunLoop::registerRunLoopMessageWindowClass):
+ Changed the return type from bool to void, and added RELEASE_ASSERT to check the return value of RegisterClass.
+
+ (WTF::RunLoop::~RunLoop):
+ When the RunLoop's thread is freed, its associated window is freed. We do not need to do here.
+
+ (WTF::RunLoop::TimerBase::timerFired):
+ (WTF::RunLoop::TimerBase::TimerBase):
+ (WTF::RunLoop::TimerBase::start):
+ (WTF::RunLoop::TimerBase::stop):
+ (WTF::RunLoop::TimerBase::isActive const):
+ (WTF::RunLoop::TimerBase::secondsUntilFire const):
+ (WTF::generateTimerID): Deleted.
+ We can use TimerBase's pointer as ID since it is uintptr_t.
+
2019-03-07 Said Abou-Hallawa <[email protected]>
requestAnimationFrame should execute before the next frame
Modified: trunk/Source/WTF/wtf/RunLoop.h (242693 => 242694)
--- trunk/Source/WTF/wtf/RunLoop.h 2019-03-11 00:27:22 UTC (rev 242693)
+++ trunk/Source/WTF/wtf/RunLoop.h 2019-03-11 02:36:23 UTC (rev 242694)
@@ -68,11 +68,15 @@
WTF_EXPORT_PRIVATE GMainContext* mainContext() const { return m_mainContext.get(); }
#endif
-#if USE(GENERIC_EVENT_LOOP)
+#if USE(GENERIC_EVENT_LOOP) || USE(WINDOWS_EVENT_LOOP)
// Run the single iteration of the RunLoop. It consumes the pending tasks and expired timers, but it won't be blocked.
WTF_EXPORT_PRIVATE static void iterate();
#endif
+#if USE(WINDOWS_EVENT_LOOP)
+ static void registerRunLoopMessageWindowClass();
+#endif
+
#if USE(GLIB_EVENT_LOOP) || USE(GENERIC_EVENT_LOOP)
WTF_EXPORT_PRIVATE void dispatchAfter(Seconds, Function<void()>&&);
#endif
@@ -110,11 +114,11 @@
#if USE(WINDOWS_EVENT_LOOP)
bool isActive(const AbstractLocker&) const;
- static void timerFired(RunLoop*, uint64_t ID);
- uint64_t m_ID;
+ void timerFired();
MonotonicTime m_nextFireDate;
Seconds m_interval;
- bool m_isRepeating;
+ bool m_isRepeating { false };
+ bool m_isActive { false };
#elif USE(COCOA_EVENT_LOOP)
static void timerFired(CFRunLoopTimerRef, void*);
RetainPtr<CFRunLoopTimerRef> m_timer;
@@ -139,8 +143,8 @@
Timer(RunLoop& runLoop, TimerFiredClass* o, TimerFiredFunction f)
: TimerBase(runLoop)
+ , m_function(f)
, m_object(o)
- , m_function(f)
{
}
@@ -147,8 +151,10 @@
private:
void fired() override { (m_object->*m_function)(); }
+ // This order should be maintained due to MSVC bug.
+ // http://computer-programming-forum.com/7-vc.net/6fbc30265f860ad1.htm
+ TimerFiredFunction m_function;
TimerFiredClass* m_object;
- TimerFiredFunction m_function;
};
class Holder;
@@ -162,14 +168,11 @@
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;
+ Lock m_loopLock;
#elif USE(COCOA_EVENT_LOOP)
static void performWork(void*);
RetainPtr<CFRunLoopRef> m_runLoop;
Modified: trunk/Source/WTF/wtf/win/MainThreadWin.cpp (242693 => 242694)
--- trunk/Source/WTF/wtf/win/MainThreadWin.cpp 2019-03-11 00:27:22 UTC (rev 242693)
+++ trunk/Source/WTF/wtf/win/MainThreadWin.cpp 2019-03-11 02:36:23 UTC (rev 242694)
@@ -31,6 +31,7 @@
#include <wtf/MainThread.h>
#include <wtf/Assertions.h>
+#include <wtf/RunLoop.h>
#include <wtf/Threading.h>
#include <wtf/WindowsExtras.h>
@@ -68,6 +69,7 @@
mainThread = Thread::currentID();
Thread::initializeCurrentThreadInternal("Main Thread");
+ RunLoop::registerRunLoopMessageWindowClass();
}
bool isMainThread()
Modified: trunk/Source/WTF/wtf/win/RunLoopWin.cpp (242693 => 242694)
--- trunk/Source/WTF/wtf/win/RunLoopWin.cpp 2019-03-11 00:27:22 UTC (rev 242693)
+++ trunk/Source/WTF/wtf/win/RunLoopWin.cpp 2019-03-11 02:36:23 UTC (rev 242694)
@@ -56,7 +56,7 @@
performWork();
return 0;
case WM_TIMER:
- RunLoop::TimerBase::timerFired(this, wParam);
+ bitwise_cast<RunLoop::TimerBase*>(wParam)->timerFired();
return 0;
}
@@ -74,27 +74,36 @@
}
}
+void RunLoop::iterate()
+{
+ MSG message;
+ while (::PeekMessage(&message, 0, 0, 0, PM_REMOVE)) {
+ ::TranslateMessage(&message);
+ ::DispatchMessage(&message);
+ }
+}
+
void RunLoop::stop()
{
- ::PostQuitMessage(0);
+ // RunLoop::stop() can be called from threads unrelated to this RunLoop.
+ // We should post a message that call PostQuitMessage in RunLoop's thread.
+ dispatch([] {
+ ::PostQuitMessage(0);
+ });
}
-bool RunLoop::registerRunLoopMessageWindowClass()
+void RunLoop::registerRunLoopMessageWindowClass()
{
- // FIXME: This really only needs to be called once.
-
- WNDCLASS windowClass { };
+ WNDCLASS windowClass = { };
windowClass.lpfnWndProc = RunLoop::RunLoopWndProc;
windowClass.cbWndExtra = sizeof(RunLoop*);
windowClass.lpszClassName = kRunLoopMessageWindowClassName;
-
- return !!::RegisterClass(&windowClass);
+ bool result = ::RegisterClass(&windowClass);
+ RELEASE_ASSERT(result);
}
RunLoop::RunLoop()
{
- registerRunLoopMessageWindowClass();
-
m_runLoopMessageWindow = ::CreateWindow(kRunLoopMessageWindowClassName, 0, 0,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, 0, this);
ASSERT(::IsWindow(m_runLoopMessageWindow));
@@ -102,7 +111,6 @@
RunLoop::~RunLoop()
{
- // FIXME: Tear down the work item queue here.
}
void RunLoop::wakeUp()
@@ -114,39 +122,26 @@
// RunLoop::Timer
-void RunLoop::TimerBase::timerFired(RunLoop* runLoop, uint64_t ID)
+void RunLoop::TimerBase::timerFired()
{
- 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.
+ LockHolder locker(m_runLoop->m_loopLock);
+
+ if (!m_isActive)
return;
- }
- timer = it->value;
-
- if (!timer->m_isRepeating) {
- runLoop->m_activeTimers.remove(it);
- ::KillTimer(runLoop->m_runLoopMessageWindow, ID);
+ if (!m_isRepeating) {
+ m_isActive = false;
+ ::KillTimer(m_runLoop->m_runLoopMessageWindow, bitwise_cast<uintptr_t>(this));
} else
- timer->m_nextFireDate = MonotonicTime::now() + timer->m_interval;
+ m_nextFireDate = MonotonicTime::now() + m_interval;
}
- timer->fired();
+ 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)
{
}
@@ -157,43 +152,41 @@
void RunLoop::TimerBase::start(Seconds nextFireInterval, bool repeat)
{
- LockHolder locker(m_runLoop->m_activeTimersLock);
+ LockHolder locker(m_runLoop->m_loopLock);
m_isRepeating = repeat;
- m_runLoop->m_activeTimers.set(m_ID, this);
+ m_isActive = true;
m_interval = nextFireInterval;
m_nextFireDate = MonotonicTime::now() + m_interval;
- ::SetTimer(m_runLoop->m_runLoopMessageWindow, m_ID, nextFireInterval.millisecondsAs<unsigned>(), 0);
+ ::SetTimer(m_runLoop->m_runLoopMessageWindow, bitwise_cast<uintptr_t>(this), nextFireInterval.millisecondsAs<UINT>(), 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())
+ LockHolder locker(m_runLoop->m_loopLock);
+ if (!isActive(locker))
return;
- m_runLoop->m_activeTimers.remove(it);
- ::KillTimer(m_runLoop->m_runLoopMessageWindow, m_ID);
+ m_isActive = false;
+ ::KillTimer(m_runLoop->m_runLoopMessageWindow, bitwise_cast<uintptr_t>(this));
}
bool RunLoop::TimerBase::isActive(const AbstractLocker&) const
{
- return m_runLoop->m_activeTimers.contains(m_ID);
+ return m_isActive;
}
bool RunLoop::TimerBase::isActive() const
{
- LockHolder locker(m_runLoop->m_activeTimersLock);
+ LockHolder locker(m_runLoop->m_loopLock);
return isActive(locker);
}
Seconds RunLoop::TimerBase::secondsUntilFire() const
{
- LockHolder locker(m_runLoop->m_activeTimersLock);
+ LockHolder locker(m_runLoop->m_loopLock);
if (isActive(locker))
return std::max<Seconds>(m_nextFireDate - MonotonicTime::now(), 0_s);
return 0_s;
}
-
} // namespace WTF
Modified: trunk/Tools/ChangeLog (242693 => 242694)
--- trunk/Tools/ChangeLog 2019-03-11 00:27:22 UTC (rev 242693)
+++ trunk/Tools/ChangeLog 2019-03-11 02:36:23 UTC (rev 242694)
@@ -1,3 +1,23 @@
+2019-03-10 Yusuke Suzuki <[email protected]>
+
+ [WTF] Align assumption in RunLoopWin to the other platform's RunLoop
+ https://bugs.webkit.org/show_bug.cgi?id=181151
+
+ Reviewed by Don Olmstead.
+
+ * TestWebKitAPI/CMakeLists.txt:
+ * TestWebKitAPI/PlatformWin.cmake:
+ Enable TestWTF RunLoop tests in all platforms.
+
+ * TestWebKitAPI/Tests/WTF/RunLoop.cpp:
+ (TestWebKitAPI::DerivedOneShotTimer::DerivedOneShotTimer):
+ (TestWebKitAPI::DerivedOneShotTimer::fired):
+ (TestWebKitAPI::TEST):
+ Only a few platforms support nested RunLoop.
+
+ (TestWebKitAPI::DerivedRepeatingTimer::DerivedRepeatingTimer):
+ (TestWebKitAPI::DerivedRepeatingTimer::fired):
+
2019-03-10 David Quesada <[email protected]>
ASSERT(m_downloads.isEmpty()) fails in DownloadProxyMap::~DownloadProxyMap()
Modified: trunk/Tools/TestWebKitAPI/CMakeLists.txt (242693 => 242694)
--- trunk/Tools/TestWebKitAPI/CMakeLists.txt 2019-03-11 00:27:22 UTC (rev 242693)
+++ trunk/Tools/TestWebKitAPI/CMakeLists.txt 2019-03-11 02:36:23 UTC (rev 242694)
@@ -153,6 +153,7 @@
${TESTWEBKITAPI_DIR}/Tests/WTF/RefCounter.cpp
${TESTWEBKITAPI_DIR}/Tests/WTF/RefLogger.cpp
${TESTWEBKITAPI_DIR}/Tests/WTF/RefPtr.cpp
+ ${TESTWEBKITAPI_DIR}/Tests/WTF/RunLoop.cpp
${TESTWEBKITAPI_DIR}/Tests/WTF/SHA1.cpp
${TESTWEBKITAPI_DIR}/Tests/WTF/SaturatedArithmeticOperations.cpp
${TESTWEBKITAPI_DIR}/Tests/WTF/Scope.cpp
@@ -186,7 +187,6 @@
if (NOT WIN32)
list(APPEND TestWTF_SOURCES
${TESTWEBKITAPI_DIR}/Tests/WTF/FileSystem.cpp
- ${TESTWEBKITAPI_DIR}/Tests/WTF/RunLoop.cpp
)
endif ()
Modified: trunk/Tools/TestWebKitAPI/PlatformWin.cmake (242693 => 242694)
--- trunk/Tools/TestWebKitAPI/PlatformWin.cmake 2019-03-11 00:27:22 UTC (rev 242693)
+++ trunk/Tools/TestWebKitAPI/PlatformWin.cmake 2019-03-11 02:36:23 UTC (rev 242694)
@@ -107,6 +107,7 @@
add_library(TestWTFLib SHARED
${test_main_SOURCES}
${TestWTF_SOURCES}
+ ${TESTWEBKITAPI_DIR}/win/UtilitiesWin.cpp
)
set_target_properties(TestWTFLib PROPERTIES OUTPUT_NAME "TestWTFLib")
target_link_libraries(TestWTFLib ${test_wtf_LIBRARIES})
Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/RunLoop.cpp (242693 => 242694)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/RunLoop.cpp 2019-03-11 00:27:22 UTC (rev 242693)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/RunLoop.cpp 2019-03-11 02:36:23 UTC (rev 242694)
@@ -27,6 +27,7 @@
#include "Utilities.h"
#include <wtf/RunLoop.h>
+#include <wtf/Threading.h>
namespace TestWebKitAPI {
@@ -54,51 +55,56 @@
Util::run(&testFinished);
}
-TEST(WTF_RunLoop, NestedRunLoop)
-{
- RunLoop::initializeMainRunLoop();
+class DerivedOneShotTimer : public RunLoop::Timer<DerivedOneShotTimer> {
+public:
+ DerivedOneShotTimer(bool& testFinished)
+ : RunLoop::Timer<DerivedOneShotTimer>(RunLoop::current(), this, &DerivedOneShotTimer::fired)
+ , m_testFinished(testFinished)
+ {
+ }
- bool testFinished = false;
- RunLoop::current().dispatch([&] {
- RunLoop::current().dispatch([&] {
- testFinished = true;
- });
- Util::run(&testFinished);
- });
+ void fired()
+ {
+ m_testFinished = true;
+ stop();
+ }
- Util::run(&testFinished);
-}
+private:
+ bool& m_testFinished;
+};
+
TEST(WTF_RunLoop, OneShotTimer)
{
RunLoop::initializeMainRunLoop();
bool testFinished = false;
+ DerivedOneShotTimer timer(testFinished);
+ timer.startOneShot(100_ms);
+ Util::run(&testFinished);
+}
- class DerivedTimer : public RunLoop::Timer<DerivedTimer> {
- public:
- DerivedTimer(bool& testFinished)
- : RunLoop::Timer<DerivedTimer>(RunLoop::current(), this, &DerivedTimer::fired)
- , m_testFinished(testFinished)
- {
- }
+class DerivedRepeatingTimer : public RunLoop::Timer<DerivedRepeatingTimer> {
+public:
+ DerivedRepeatingTimer(bool& testFinished)
+ : RunLoop::Timer<DerivedRepeatingTimer>(RunLoop::current(), this, &DerivedRepeatingTimer::fired)
+ , m_testFinished(testFinished)
+ {
+ }
- void fired()
- {
+ void fired()
+ {
+ if (++m_count == 10) {
m_testFinished = true;
stop();
}
+ }
- private:
- bool& m_testFinished;
- };
+private:
+ unsigned m_count { 0 };
+ bool& m_testFinished;
+};
- {
- DerivedTimer timer(testFinished);
- timer.startOneShot(100_ms);
- Util::run(&testFinished);
- }
-}
TEST(WTF_RunLoop, RepeatingTimer)
{
@@ -105,39 +111,13 @@
RunLoop::initializeMainRunLoop();
bool testFinished = false;
-
- class DerivedTimer : public RunLoop::Timer<DerivedTimer> {
- public:
- DerivedTimer(bool& testFinished)
- : RunLoop::Timer<DerivedTimer>(RunLoop::current(), this, &DerivedTimer::fired)
- , m_testFinished(testFinished)
- {
- }
-
- void fired()
- {
- if (++m_count == 10) {
- m_testFinished = true;
- stop();
- }
- }
-
- private:
- unsigned m_count { 0 };
- bool& m_testFinished;
- };
-
- {
- DerivedTimer timer(testFinished);
- timer.startRepeating(10_ms);
- Util::run(&testFinished);
- }
+ DerivedRepeatingTimer timer(testFinished);
+ timer.startRepeating(10_ms);
+ Util::run(&testFinished);
}
TEST(WTF_RunLoop, ManyTimes)
{
- RunLoop::initializeMainRunLoop();
-
class Counter {
public:
void run()
@@ -155,12 +135,13 @@
unsigned m_count { 0 };
};
- Counter counter;
-
- RunLoop::current().dispatch([&counter] {
- counter.run();
- });
- RunLoop::run();
+ Thread::create("RunLoopManyTimes", [] {
+ Counter counter;
+ RunLoop::current().dispatch([&counter] {
+ counter.run();
+ });
+ RunLoop::run();
+ })->waitForCompletion();
}
} // namespace TestWebKitAPI