Title: [188415] trunk/Source/WTF
- Revision
- 188415
- Author
- mark....@apple.com
- Date
- 2015-08-13 16:38:57 -0700 (Thu, 13 Aug 2015)
Log Message
WorkQueue::dispatchAfter() on Windows fires early.
https://bugs.webkit.org/show_bug.cgi?id=147992
Reviewed by Brent Fulgham.
The Windows implementation of WorkQueue::dispatchAfter() uses CreateTimerQueueTimer().
Unfortunately, CreateTimerQueueTimer() is sloppy and can fire early. We need to compensate
for this slop to ensure that the specified duration does expire before the callback function
is called. Otherwise, the JSC watchdog (which depends on this) can fail randomly.
* wtf/win/WorkQueueWin.cpp:
(WTF::WorkQueue::dispatchAfter):
Modified Paths
Diff
Modified: trunk/Source/WTF/ChangeLog (188414 => 188415)
--- trunk/Source/WTF/ChangeLog 2015-08-13 23:26:57 UTC (rev 188414)
+++ trunk/Source/WTF/ChangeLog 2015-08-13 23:38:57 UTC (rev 188415)
@@ -1,3 +1,18 @@
+2015-08-13 Mark Lam <mark....@apple.com>
+
+ WorkQueue::dispatchAfter() on Windows fires early.
+ https://bugs.webkit.org/show_bug.cgi?id=147992
+
+ Reviewed by Brent Fulgham.
+
+ The Windows implementation of WorkQueue::dispatchAfter() uses CreateTimerQueueTimer().
+ Unfortunately, CreateTimerQueueTimer() is sloppy and can fire early. We need to compensate
+ for this slop to ensure that the specified duration does expire before the callback function
+ is called. Otherwise, the JSC watchdog (which depends on this) can fail randomly.
+
+ * wtf/win/WorkQueueWin.cpp:
+ (WTF::WorkQueue::dispatchAfter):
+
2015-08-13 Filip Pizlo <fpi...@apple.com>
WTF should have a compact Condition object to use with Lock
Modified: trunk/Source/WTF/wtf/win/WorkQueueWin.cpp (188414 => 188415)
--- trunk/Source/WTF/wtf/win/WorkQueueWin.cpp 2015-08-13 23:26:57 UTC (rev 188414)
+++ trunk/Source/WTF/wtf/win/WorkQueueWin.cpp 2015-08-13 23:38:57 UTC (rev 188415)
@@ -195,9 +195,22 @@
// timer handle has been stored in it.
MutexLocker lock(context->timerMutex);
+ int64_t milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
+
+ // 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.
- int64_t milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
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;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes