Changeset 242694 in webkit
- Timestamp:
- Mar 10, 2019, 7:36:23 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
-
Source/WTF/ChangeLog (modified) (1 diff)
-
Source/WTF/wtf/RunLoop.h (modified) (5 diffs)
-
Source/WTF/wtf/win/MainThreadWin.cpp (modified) (2 diffs)
-
Source/WTF/wtf/win/RunLoopWin.cpp (modified) (7 diffs)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/CMakeLists.txt (modified) (2 diffs)
-
Tools/TestWebKitAPI/PlatformWin.cmake (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WTF/RunLoop.cpp (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WTF/ChangeLog
r242624 r242694 1 2019-03-10 Yusuke Suzuki <utatane.tea@gmail.com> and Fujii Hironori <Hironori.Fujii@sony.com> 2 3 [WTF] Align assumption in RunLoopWin to the other platform's RunLoop 4 https://bugs.webkit.org/show_bug.cgi?id=181151 5 6 Reviewed by Don Olmstead. 7 8 This patch fixes RunLoop in Windows to align it to the implementations in the other platforms 9 to use RunLoop more aggressively. 10 11 * wtf/RunLoop.h: 12 (WTF::RunLoop::Timer::Timer): 13 * wtf/win/MainThreadWin.cpp: 14 (initializeMainThreadPlatform): Call RunLoop::registerRunLoopMessageWindowClass. 15 * wtf/win/RunLoopWin.cpp: 16 (WTF::RunLoop::wndProc): 17 (WTF::RunLoop::iterate): 18 (WTF::RunLoop::stop): 19 PostQuitMessage is only available in the RunLoop's thread. We should post a message and call 20 it inside this task. 21 22 (WTF::RunLoop::registerRunLoopMessageWindowClass): 23 Changed the return type from bool to void, and added RELEASE_ASSERT to check the return value of RegisterClass. 24 25 (WTF::RunLoop::~RunLoop): 26 When the RunLoop's thread is freed, its associated window is freed. We do not need to do here. 27 28 (WTF::RunLoop::TimerBase::timerFired): 29 (WTF::RunLoop::TimerBase::TimerBase): 30 (WTF::RunLoop::TimerBase::start): 31 (WTF::RunLoop::TimerBase::stop): 32 (WTF::RunLoop::TimerBase::isActive const): 33 (WTF::RunLoop::TimerBase::secondsUntilFire const): 34 (WTF::generateTimerID): Deleted. 35 We can use TimerBase's pointer as ID since it is uintptr_t. 36 1 37 2019-03-07 Said Abou-Hallawa <sabouhallawa@apple.com> 2 38 -
trunk/Source/WTF/wtf/RunLoop.h
r237099 r242694 69 69 #endif 70 70 71 #if USE(GENERIC_EVENT_LOOP) 71 #if USE(GENERIC_EVENT_LOOP) || USE(WINDOWS_EVENT_LOOP) 72 72 // Run the single iteration of the RunLoop. It consumes the pending tasks and expired timers, but it won't be blocked. 73 73 WTF_EXPORT_PRIVATE static void iterate(); 74 #endif 75 76 #if USE(WINDOWS_EVENT_LOOP) 77 static void registerRunLoopMessageWindowClass(); 74 78 #endif 75 79 … … 111 115 #if USE(WINDOWS_EVENT_LOOP) 112 116 bool isActive(const AbstractLocker&) const; 113 static void timerFired(RunLoop*, uint64_t ID); 114 uint64_t m_ID; 117 void timerFired(); 115 118 MonotonicTime m_nextFireDate; 116 119 Seconds m_interval; 117 bool m_isRepeating; 120 bool m_isRepeating { false }; 121 bool m_isActive { false }; 118 122 #elif USE(COCOA_EVENT_LOOP) 119 123 static void timerFired(CFRunLoopTimerRef, void*); … … 140 144 Timer(RunLoop& runLoop, TimerFiredClass* o, TimerFiredFunction f) 141 145 : TimerBase(runLoop) 146 , m_function(f) 142 147 , m_object(o) 143 , m_function(f)144 148 { 145 149 } … … 148 152 void fired() override { (m_object->*m_function)(); } 149 153 154 // This order should be maintained due to MSVC bug. 155 // http://computer-programming-forum.com/7-vc.net/6fbc30265f860ad1.htm 156 TimerFiredFunction m_function; 150 157 TimerFiredClass* m_object; 151 TimerFiredFunction m_function;152 158 }; 153 159 … … 163 169 164 170 #if USE(WINDOWS_EVENT_LOOP) 165 static bool registerRunLoopMessageWindowClass();166 171 static LRESULT CALLBACK RunLoopWndProc(HWND, UINT, WPARAM, LPARAM); 167 172 LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); 168 173 HWND m_runLoopMessageWindow; 169 174 170 typedef HashMap<uint64_t, TimerBase*> TimerMap; 171 Lock m_activeTimersLock; 172 TimerMap m_activeTimers; 175 Lock m_loopLock; 173 176 #elif USE(COCOA_EVENT_LOOP) 174 177 static void performWork(void*); -
trunk/Source/WTF/wtf/win/MainThreadWin.cpp
r237099 r242694 32 32 33 33 #include <wtf/Assertions.h> 34 #include <wtf/RunLoop.h> 34 35 #include <wtf/Threading.h> 35 36 #include <wtf/WindowsExtras.h> … … 69 70 70 71 Thread::initializeCurrentThreadInternal("Main Thread"); 72 RunLoop::registerRunLoopMessageWindowClass(); 71 73 } 72 74 -
trunk/Source/WTF/wtf/win/RunLoopWin.cpp
r239093 r242694 57 57 return 0; 58 58 case WM_TIMER: 59 RunLoop::TimerBase::timerFired(this, wParam);59 bitwise_cast<RunLoop::TimerBase*>(wParam)->timerFired(); 60 60 return 0; 61 61 } … … 75 75 } 76 76 77 void RunLoop::iterate() 78 { 79 MSG message; 80 while (::PeekMessage(&message, 0, 0, 0, PM_REMOVE)) { 81 ::TranslateMessage(&message); 82 ::DispatchMessage(&message); 83 } 84 } 85 77 86 void RunLoop::stop() 78 87 { 79 ::PostQuitMessage(0); 88 // RunLoop::stop() can be called from threads unrelated to this RunLoop. 89 // We should post a message that call PostQuitMessage in RunLoop's thread. 90 dispatch([] { 91 ::PostQuitMessage(0); 92 }); 80 93 } 81 94 82 boolRunLoop::registerRunLoopMessageWindowClass()95 void RunLoop::registerRunLoopMessageWindowClass() 83 96 { 84 // FIXME: This really only needs to be called once. 85 86 WNDCLASS windowClass { }; 97 WNDCLASS windowClass = { }; 87 98 windowClass.lpfnWndProc = RunLoop::RunLoopWndProc; 88 99 windowClass.cbWndExtra = sizeof(RunLoop*); 89 100 windowClass.lpszClassName = kRunLoopMessageWindowClassName; 90 91 return !!::RegisterClass(&windowClass);101 bool result = ::RegisterClass(&windowClass); 102 RELEASE_ASSERT(result); 92 103 } 93 104 94 105 RunLoop::RunLoop() 95 106 { 96 registerRunLoopMessageWindowClass();97 98 107 m_runLoopMessageWindow = ::CreateWindow(kRunLoopMessageWindowClassName, 0, 0, 99 108 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, 0, this); … … 103 112 RunLoop::~RunLoop() 104 113 { 105 // FIXME: Tear down the work item queue here.106 114 } 107 115 … … 115 123 // RunLoop::Timer 116 124 117 void RunLoop::TimerBase::timerFired( RunLoop* runLoop, uint64_t ID)125 void RunLoop::TimerBase::timerFired() 118 126 { 119 TimerBase* timer = nullptr;120 127 { 121 LockHolder locker(runLoop->m_activeTimersLock); 122 TimerMap::iterator it = runLoop->m_activeTimers.find(ID); 123 if (it == runLoop->m_activeTimers.end()) { 124 // The timer must have been stopped after the WM_TIMER message was posted to the message queue. 128 LockHolder locker(m_runLoop->m_loopLock); 129 130 if (!m_isActive) 125 131 return; 126 }127 132 128 timer = it->value; 129 130 if (!timer->m_isRepeating) { 131 runLoop->m_activeTimers.remove(it); 132 ::KillTimer(runLoop->m_runLoopMessageWindow, ID); 133 if (!m_isRepeating) { 134 m_isActive = false; 135 ::KillTimer(m_runLoop->m_runLoopMessageWindow, bitwise_cast<uintptr_t>(this)); 133 136 } else 134 timer->m_nextFireDate = MonotonicTime::now() + timer->m_interval;137 m_nextFireDate = MonotonicTime::now() + m_interval; 135 138 } 136 139 137 timer->fired(); 138 } 139 140 static uint64_t generateTimerID() 141 { 142 static uint64_t uniqueTimerID = 1; 143 return uniqueTimerID++; 140 fired(); 144 141 } 145 142 146 143 RunLoop::TimerBase::TimerBase(RunLoop& runLoop) 147 144 : m_runLoop(runLoop) 148 , m_ID(generateTimerID())149 , m_isRepeating(false)150 145 { 151 146 } … … 158 153 void RunLoop::TimerBase::start(Seconds nextFireInterval, bool repeat) 159 154 { 160 LockHolder locker(m_runLoop->m_ activeTimersLock);155 LockHolder locker(m_runLoop->m_loopLock); 161 156 m_isRepeating = repeat; 162 m_ runLoop->m_activeTimers.set(m_ID, this);157 m_isActive = true; 163 158 m_interval = nextFireInterval; 164 159 m_nextFireDate = MonotonicTime::now() + m_interval; 165 ::SetTimer(m_runLoop->m_runLoopMessageWindow, m_ID, nextFireInterval.millisecondsAs<unsigned>(), 0);160 ::SetTimer(m_runLoop->m_runLoopMessageWindow, bitwise_cast<uintptr_t>(this), nextFireInterval.millisecondsAs<UINT>(), 0); 166 161 } 167 162 168 163 void RunLoop::TimerBase::stop() 169 164 { 170 LockHolder locker(m_runLoop->m_activeTimersLock); 171 TimerMap::iterator it = m_runLoop->m_activeTimers.find(m_ID); 172 if (it == m_runLoop->m_activeTimers.end()) 165 LockHolder locker(m_runLoop->m_loopLock); 166 if (!isActive(locker)) 173 167 return; 174 168 175 m_ runLoop->m_activeTimers.remove(it);176 ::KillTimer(m_runLoop->m_runLoopMessageWindow, m_ID);169 m_isActive = false; 170 ::KillTimer(m_runLoop->m_runLoopMessageWindow, bitwise_cast<uintptr_t>(this)); 177 171 } 178 172 179 173 bool RunLoop::TimerBase::isActive(const AbstractLocker&) const 180 174 { 181 return m_ runLoop->m_activeTimers.contains(m_ID);175 return m_isActive; 182 176 } 183 177 184 178 bool RunLoop::TimerBase::isActive() const 185 179 { 186 LockHolder locker(m_runLoop->m_ activeTimersLock);180 LockHolder locker(m_runLoop->m_loopLock); 187 181 return isActive(locker); 188 182 } … … 190 184 Seconds RunLoop::TimerBase::secondsUntilFire() const 191 185 { 192 LockHolder locker(m_runLoop->m_ activeTimersLock);186 LockHolder locker(m_runLoop->m_loopLock); 193 187 if (isActive(locker)) 194 188 return std::max<Seconds>(m_nextFireDate - MonotonicTime::now(), 0_s); … … 196 190 } 197 191 198 199 192 } // namespace WTF -
trunk/Tools/ChangeLog
r242693 r242694 1 2019-03-10 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [WTF] Align assumption in RunLoopWin to the other platform's RunLoop 4 https://bugs.webkit.org/show_bug.cgi?id=181151 5 6 Reviewed by Don Olmstead. 7 8 * TestWebKitAPI/CMakeLists.txt: 9 * TestWebKitAPI/PlatformWin.cmake: 10 Enable TestWTF RunLoop tests in all platforms. 11 12 * TestWebKitAPI/Tests/WTF/RunLoop.cpp: 13 (TestWebKitAPI::DerivedOneShotTimer::DerivedOneShotTimer): 14 (TestWebKitAPI::DerivedOneShotTimer::fired): 15 (TestWebKitAPI::TEST): 16 Only a few platforms support nested RunLoop. 17 18 (TestWebKitAPI::DerivedRepeatingTimer::DerivedRepeatingTimer): 19 (TestWebKitAPI::DerivedRepeatingTimer::fired): 20 1 21 2019-03-10 David Quesada <david_quesada@apple.com> 2 22 -
trunk/Tools/TestWebKitAPI/CMakeLists.txt
r242127 r242694 154 154 ${TESTWEBKITAPI_DIR}/Tests/WTF/RefLogger.cpp 155 155 ${TESTWEBKITAPI_DIR}/Tests/WTF/RefPtr.cpp 156 ${TESTWEBKITAPI_DIR}/Tests/WTF/RunLoop.cpp 156 157 ${TESTWEBKITAPI_DIR}/Tests/WTF/SHA1.cpp 157 158 ${TESTWEBKITAPI_DIR}/Tests/WTF/SaturatedArithmeticOperations.cpp … … 187 188 list(APPEND TestWTF_SOURCES 188 189 ${TESTWEBKITAPI_DIR}/Tests/WTF/FileSystem.cpp 189 ${TESTWEBKITAPI_DIR}/Tests/WTF/RunLoop.cpp190 190 ) 191 191 endif () -
trunk/Tools/TestWebKitAPI/PlatformWin.cmake
r242279 r242694 108 108 ${test_main_SOURCES} 109 109 ${TestWTF_SOURCES} 110 ${TESTWEBKITAPI_DIR}/win/UtilitiesWin.cpp 110 111 ) 111 112 set_target_properties(TestWTFLib PROPERTIES OUTPUT_NAME "TestWTFLib") -
trunk/Tools/TestWebKitAPI/Tests/WTF/RunLoop.cpp
r235788 r242694 28 28 #include "Utilities.h" 29 29 #include <wtf/RunLoop.h> 30 #include <wtf/Threading.h> 30 31 31 32 namespace TestWebKitAPI { … … 55 56 } 56 57 57 TEST(WTF_RunLoop, NestedRunLoop) 58 { 59 RunLoop::initializeMainRunLoop(); 58 class DerivedOneShotTimer : public RunLoop::Timer<DerivedOneShotTimer> { 59 public: 60 DerivedOneShotTimer(bool& testFinished) 61 : RunLoop::Timer<DerivedOneShotTimer>(RunLoop::current(), this, &DerivedOneShotTimer::fired) 62 , m_testFinished(testFinished) 63 { 64 } 60 65 61 bool testFinished = false; 62 RunLoop::current().dispatch([&] { 63 RunLoop::current().dispatch([&] { 64 testFinished = true; 65 }); 66 Util::run(&testFinished); 67 }); 66 void fired() 67 { 68 m_testFinished = true; 69 stop(); 70 } 68 71 69 Util::run(&testFinished); 70 } 72 private: 73 bool& m_testFinished; 74 }; 75 71 76 72 77 TEST(WTF_RunLoop, OneShotTimer) … … 75 80 76 81 bool testFinished = false; 82 DerivedOneShotTimer timer(testFinished); 83 timer.startOneShot(100_ms); 84 Util::run(&testFinished); 85 } 77 86 78 class DerivedTimer : public RunLoop::Timer<DerivedTimer> {79 public:80 DerivedTimer(bool& testFinished)81 : RunLoop::Timer<DerivedTimer>(RunLoop::current(), this, &DerivedTimer::fired)82 , m_testFinished(testFinished)83 {84 }87 class DerivedRepeatingTimer : public RunLoop::Timer<DerivedRepeatingTimer> { 88 public: 89 DerivedRepeatingTimer(bool& testFinished) 90 : RunLoop::Timer<DerivedRepeatingTimer>(RunLoop::current(), this, &DerivedRepeatingTimer::fired) 91 , m_testFinished(testFinished) 92 { 93 } 85 94 86 void fired() 87 { 95 void fired() 96 { 97 if (++m_count == 10) { 88 98 m_testFinished = true; 89 99 stop(); 90 100 } 101 } 91 102 92 private: 93 bool& m_testFinished; 94 }; 103 private: 104 unsigned m_count { 0 }; 105 bool& m_testFinished; 106 }; 95 107 96 {97 DerivedTimer timer(testFinished);98 timer.startOneShot(100_ms);99 Util::run(&testFinished);100 }101 }102 108 103 109 TEST(WTF_RunLoop, RepeatingTimer) … … 106 112 107 113 bool testFinished = false; 108 109 class DerivedTimer : public RunLoop::Timer<DerivedTimer> { 110 public: 111 DerivedTimer(bool& testFinished) 112 : RunLoop::Timer<DerivedTimer>(RunLoop::current(), this, &DerivedTimer::fired) 113 , m_testFinished(testFinished) 114 { 115 } 116 117 void fired() 118 { 119 if (++m_count == 10) { 120 m_testFinished = true; 121 stop(); 122 } 123 } 124 125 private: 126 unsigned m_count { 0 }; 127 bool& m_testFinished; 128 }; 129 130 { 131 DerivedTimer timer(testFinished); 132 timer.startRepeating(10_ms); 133 Util::run(&testFinished); 134 } 114 DerivedRepeatingTimer timer(testFinished); 115 timer.startRepeating(10_ms); 116 Util::run(&testFinished); 135 117 } 136 118 137 119 TEST(WTF_RunLoop, ManyTimes) 138 120 { 139 RunLoop::initializeMainRunLoop();140 141 121 class Counter { 142 122 public: … … 156 136 }; 157 137 158 Counter counter; 159 160 RunLoop::current().dispatch([&counter] { 161 counter.run(); 162 }); 163 RunLoop::run(); 138 Thread::create("RunLoopManyTimes", [] { 139 Counter counter; 140 RunLoop::current().dispatch([&counter] { 141 counter.run(); 142 }); 143 RunLoop::run(); 144 })->waitForCompletion(); 164 145 } 165 146
Note:
See TracChangeset
for help on using the changeset viewer.