Title: [143210] trunk/Source/WebCore
Revision
143210
Author
[email protected]
Date
2013-02-18 06:28:28 -0800 (Mon, 18 Feb 2013)

Log Message

Reschedule shared CFRunLoopTimer instead of reconstructing it
https://bugs.webkit.org/show_bug.cgi?id=109765

Reviewed by Andreas Kling.

Using CFRunLoopTimerSetNextFireDate is over 2x faster than deleting and reconstructing timers.

* platform/SharedTimer.h:
(WebCore::SharedTimer::willEnterNestedEventLoop):
(WebCore):
(MainThreadSharedTimer):
(WebCore::MainThreadSharedTimer::willEnterNestedEventLoop):
* platform/ThreadTimers.cpp:
(WebCore::ThreadTimers::fireTimersInNestedEventLoop):
* platform/mac/SharedTimerMac.mm:
(WebCore):
(WebCore::PowerObserver::clearSharedTimer):
(WebCore::ensurePowerObserver):
(WebCore::sharedTimer):
(WebCore::reinsertSharedTimer):
        
    Before entering nested runloop (used for inspector debugger mostly) reconstruct and reinsert the timer. For some reason
    the timer doesn't fire otherwise.

(WebCore::setSharedTimerFireInterval):
(WebCore::stopSharedTimer):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (143209 => 143210)


--- trunk/Source/WebCore/ChangeLog	2013-02-18 14:10:27 UTC (rev 143209)
+++ trunk/Source/WebCore/ChangeLog	2013-02-18 14:28:28 UTC (rev 143210)
@@ -1,3 +1,32 @@
+2013-02-16  Antti Koivisto  <[email protected]>
+
+        Reschedule shared CFRunLoopTimer instead of reconstructing it
+        https://bugs.webkit.org/show_bug.cgi?id=109765
+
+        Reviewed by Andreas Kling.
+
+        Using CFRunLoopTimerSetNextFireDate is over 2x faster than deleting and reconstructing timers.
+
+        * platform/SharedTimer.h:
+        (WebCore::SharedTimer::willEnterNestedEventLoop):
+        (WebCore):
+        (MainThreadSharedTimer):
+        (WebCore::MainThreadSharedTimer::willEnterNestedEventLoop):
+        * platform/ThreadTimers.cpp:
+        (WebCore::ThreadTimers::fireTimersInNestedEventLoop):
+        * platform/mac/SharedTimerMac.mm:
+        (WebCore):
+        (WebCore::PowerObserver::clearSharedTimer):
+        (WebCore::ensurePowerObserver):
+        (WebCore::sharedTimer):
+        (WebCore::reinsertSharedTimer):
+        
+            Before entering nested runloop (used for inspector debugger mostly) reconstruct and reinsert the timer. For some reason
+            the timer doesn't fire otherwise.
+
+        (WebCore::setSharedTimerFireInterval):
+        (WebCore::stopSharedTimer):
+
 2013-02-18  Alexander Pavlov  <[email protected]>
 
         Web Inspector: [Resources] Only remember the tree element selection if explicitly made by user

Modified: trunk/Source/WebCore/platform/SharedTimer.h (143209 => 143210)


--- trunk/Source/WebCore/platform/SharedTimer.h	2013-02-18 14:10:27 UTC (rev 143209)
+++ trunk/Source/WebCore/platform/SharedTimer.h	2013-02-18 14:28:28 UTC (rev 143210)
@@ -44,6 +44,7 @@
         // The fire interval is in seconds relative to the current monotonic clock time.
         virtual void setFireInterval(double) = 0;
         virtual void stop() = 0;
+        virtual void willEnterNestedEventLoop() { ASSERT_NOT_REACHED(); }
     };
 
 
@@ -52,7 +53,9 @@
     void setSharedTimerFiredFunction(void (*)());
     void setSharedTimerFireInterval(double);
     void stopSharedTimer();
-
+#if PLATFORM(MAC)
+    void clearSharedTimer();
+#endif
     // Implementation of SharedTimer for the main thread.
     class MainThreadSharedTimer : public SharedTimer {
     public:
@@ -70,6 +73,13 @@
         {
             stopSharedTimer();
         }
+
+        virtual void willEnterNestedEventLoop()
+        {
+#if PLATFORM(MAC)
+            clearSharedTimer();
+#endif
+        }
     };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/ThreadTimers.cpp (143209 => 143210)


--- trunk/Source/WebCore/platform/ThreadTimers.cpp	2013-02-18 14:10:27 UTC (rev 143209)
+++ trunk/Source/WebCore/platform/ThreadTimers.cpp	2013-02-18 14:28:28 UTC (rev 143210)
@@ -142,6 +142,7 @@
 {
     // Reset the reentrancy guard so the timers can fire again.
     m_firingTimers = false;
+    m_sharedTimer->willEnterNestedEventLoop();
     updateSharedTimer();
 }
 

Modified: trunk/Source/WebCore/platform/mac/SharedTimerMac.mm (143209 => 143210)


--- trunk/Source/WebCore/platform/mac/SharedTimerMac.mm	2013-02-18 14:10:27 UTC (rev 143209)
+++ trunk/Source/WebCore/platform/mac/SharedTimerMac.mm	2013-02-18 14:28:28 UTC (rev 143210)
@@ -42,7 +42,7 @@
 
 namespace WebCore {
 
-static CFRunLoopTimerRef sharedTimer;
+static const CFTimeInterval distantFuture = 60 * 60 * 24 * 365 * 10; // Decade.
 static void (*sharedTimerFiredFunction)();
 static void timerFired(CFRunLoopTimerRef, void*);
 
@@ -143,15 +143,39 @@
 {
     ASSERT(CFRunLoopGetCurrent() == CFRunLoopGetMain());
 
-    if (!sharedTimer)
-        return;
-
     stopSharedTimer();
     timerFired(0, 0);
 }
 
-static PowerObserver* PowerObserver;
+static void ensurePowerObserver()
+{
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        static PowerObserver* powerObserver;
+        powerObserver = PowerObserver::create().leakPtr();
+    });
+}
 
+static CFRunLoopTimerRef globalSharedTimer;
+
+static CFRunLoopTimerRef sharedTimer()
+{
+    if (!globalSharedTimer) {
+        globalSharedTimer = CFRunLoopTimerCreate(0, CFAbsoluteTimeGetCurrent() + distantFuture, distantFuture, 0, 0, timerFired, 0);
+        CFRunLoopAddTimer(CFRunLoopGetCurrent(), globalSharedTimer, kCFRunLoopCommonModes);
+        ensurePowerObserver();
+    }
+    return globalSharedTimer;
+};
+
+void clearSharedTimer()
+{
+    // For some reason the timer won't fire in a nested runloop unless it has been freshly created and inserted.
+    CFRunLoopTimerInvalidate(globalSharedTimer);
+    CFRelease(globalSharedTimer);
+    globalSharedTimer = 0;
+}
+
 void setSharedTimerFiredFunction(void (*f)())
 {
     ASSERT(!sharedTimerFiredFunction || sharedTimerFiredFunction == f);
@@ -170,27 +194,13 @@
 void setSharedTimerFireInterval(double interval)
 {
     ASSERT(sharedTimerFiredFunction);
-
-    if (sharedTimer) {
-        CFRunLoopTimerInvalidate(sharedTimer);
-        CFRelease(sharedTimer);
-    }
-
     CFAbsoluteTime fireDate = CFAbsoluteTimeGetCurrent() + interval;
-    sharedTimer = CFRunLoopTimerCreate(0, fireDate, 0, 0, 0, timerFired, 0);
-    CFRunLoopAddTimer(CFRunLoopGetCurrent(), sharedTimer, kCFRunLoopCommonModes);
-    
-    if (!PowerObserver)
-        PowerObserver = PowerObserver::create().leakPtr();
+    CFRunLoopTimerSetNextFireDate(sharedTimer(), fireDate);
 }
 
 void stopSharedTimer()
 {
-    if (sharedTimer) {
-        CFRunLoopTimerInvalidate(sharedTimer);
-        CFRelease(sharedTimer);
-        sharedTimer = 0;
-    }
+    CFRunLoopTimerSetNextFireDate(sharedTimer(), CFAbsoluteTimeGetCurrent() + distantFuture);
 }
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to