Make timerNestingLevel threadsafe
authorbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 30 Aug 2014 01:33:24 +0000 (01:33 +0000)
committerbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 30 Aug 2014 01:33:24 +0000 (01:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=136401

Reviewed by Tim Horton.

timerNestingLevel, used by DOMTimer to determine whether a timer is 'nested'
(repeating, possible due to a timer rescheduling itself) is a global. Since
worker threads can set timers too this is not thread safe.

* dom/ScriptExecutionContext.cpp:
(WebCore::ScriptExecutionContext::ScriptExecutionContext):
    - added initialize m_timerNestingLevel
* dom/ScriptExecutionContext.h:
(WebCore::ScriptExecutionContext::timerNestingLevel):
(WebCore::ScriptExecutionContext::setTimerNestingLevel):
    - added accessors
* page/DOMTimer.cpp:
(WebCore::DOMTimer::DOMTimer):
(WebCore::DOMTimer::fired):
    - move timerNestingLevel to the context

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@173133 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/dom/ScriptExecutionContext.cpp
Source/WebCore/dom/ScriptExecutionContext.h
Source/WebCore/page/DOMTimer.cpp

index f4fc199..e043bf5 100644 (file)
@@ -1,5 +1,28 @@
 2014-08-29  Gavin Barraclough  <barraclough@apple.com>
 
+        Make timerNestingLevel threadsafe
+        https://bugs.webkit.org/show_bug.cgi?id=136401
+
+        Reviewed by Tim Horton.
+
+        timerNestingLevel, used by DOMTimer to determine whether a timer is 'nested'
+        (repeating, possible due to a timer rescheduling itself) is a global. Since
+        worker threads can set timers too this is not thread safe.
+
+        * dom/ScriptExecutionContext.cpp:
+        (WebCore::ScriptExecutionContext::ScriptExecutionContext):
+            - added initialize m_timerNestingLevel
+        * dom/ScriptExecutionContext.h:
+        (WebCore::ScriptExecutionContext::timerNestingLevel):
+        (WebCore::ScriptExecutionContext::setTimerNestingLevel):
+            - added accessors
+        * page/DOMTimer.cpp:
+        (WebCore::DOMTimer::DOMTimer):
+        (WebCore::DOMTimer::fired):
+            - move timerNestingLevel to the context
+
+2014-08-29  Gavin Barraclough  <barraclough@apple.com>
+
         DOMTimer::m_nestingLevel is prone to overflow
         https://bugs.webkit.org/show_bug.cgi?id=136399
 
index 234d1f8..0dfd08c 100644 (file)
@@ -80,6 +80,7 @@ ScriptExecutionContext::ScriptExecutionContext()
     , m_reasonForSuspendingActiveDOMObjects(static_cast<ActiveDOMObject::ReasonForSuspension>(-1))
     , m_activeDOMObjectsAreStopped(false)
     , m_activeDOMObjectAdditionForbidden(false)
+    , m_timerNestingLevel(0)
 #if !ASSERT_DISABLED
     , m_inScriptExecutionContextDestructor(false)
     , m_activeDOMObjectRemovalForbidden(false)
index 1a819d5..c24af1c 100644 (file)
@@ -175,6 +175,9 @@ public:
     virtual bool unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key) = 0;
 #endif
 
+    int timerNestingLevel() const { return m_timerNestingLevel; }
+    void setTimerNestingLevel(int timerNestingLevel) { m_timerNestingLevel = timerNestingLevel; }
+
 protected:
     class AddConsoleMessageTask : public Task {
     public:
@@ -223,6 +226,7 @@ private:
 #endif
 
     bool m_activeDOMObjectAdditionForbidden;
+    int m_timerNestingLevel;
 
 #if !ASSERT_DISABLED
     bool m_inScriptExecutionContextDestructor;
index 844360b..9533825 100644 (file)
@@ -49,8 +49,6 @@ static const int maxIntervalForUserGestureForwarding = 1000; // One second match
 static const int maxTimerNestingLevel = 5;
 static const double oneMillisecond = 0.001;
 
-static int timerNestingLevel = 0;
-    
 static inline bool shouldForwardUserGesture(int interval, int nestingLevel)
 {
     return UserGestureIndicator::processingUserGesture()
@@ -60,7 +58,7 @@ static inline bool shouldForwardUserGesture(int interval, int nestingLevel)
 
 DOMTimer::DOMTimer(ScriptExecutionContext* context, std::unique_ptr<ScheduledAction> action, int interval, bool singleShot)
     : SuspendableTimer(context)
-    , m_nestingLevel(timerNestingLevel)
+    , m_nestingLevel(context->timerNestingLevel())
     , m_action(WTF::move(action))
     , m_originalInterval(interval)
     , m_shouldForwardUserGesture(shouldForwardUserGesture(interval, m_nestingLevel))
@@ -130,7 +128,7 @@ void DOMTimer::fired()
         ASSERT(!document->frame()->timersPaused());
     }
 #endif
-    timerNestingLevel = std::min(m_nestingLevel + 1, maxTimerNestingLevel);
+    context->setTimerNestingLevel(std::min(m_nestingLevel + 1, maxTimerNestingLevel));
 
     ASSERT(!isSuspended());
     ASSERT(!context->activeDOMObjectsAreSuspended());
@@ -192,7 +190,7 @@ void DOMTimer::fired()
 
     InspectorInstrumentation::didFireTimer(cookie);
 
-    timerNestingLevel = 0;
+    context->setTimerNestingLevel(0);
 }
 
 void DOMTimer::didStop()