Title: [102405] trunk
Revision
102405
Author
jam...@google.com
Date
2011-12-08 17:33:41 -0800 (Thu, 08 Dec 2011)

Log Message

Source/WebCore: Improve handling of frame removal during requestAnimationFrame callback invocation
https://bugs.webkit.org/show_bug.cgi?id=74036

Reviewed by Adam Barth.

See bug for details.

Test: fast/animation/request-animation-frame-detach-element.html

* dom/Document.cpp:
(WebCore::Document::removedLastRef):
(WebCore::Document::detach):
* dom/Document.h:
* dom/ScriptedAnimationController.cpp:
(WebCore::ScriptedAnimationController::~ScriptedAnimationController):
(WebCore::ScriptedAnimationController::serviceScriptedAnimations):
(WebCore::ScriptedAnimationController::scheduleAnimation):
* dom/ScriptedAnimationController.h:
(WebCore::ScriptedAnimationController::create):
(WebCore::ScriptedAnimationController::clearDocumentPointer):
* page/FrameView.cpp:
(WebCore::FrameView::serviceScriptedAnimations):

LayoutTests: Add some tests for removing frames from the document while servicing requestAnimationFrame callbacks
https://bugs.webkit.org/show_bug.cgi?id=74036

Reviewed by Adam Barth.

* fast/animation/request-animation-frame-detach-element-expected.txt: Added.
* fast/animation/request-animation-frame-detach-element.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (102404 => 102405)


--- trunk/LayoutTests/ChangeLog	2011-12-09 01:31:12 UTC (rev 102404)
+++ trunk/LayoutTests/ChangeLog	2011-12-09 01:33:41 UTC (rev 102405)
@@ -1,3 +1,13 @@
+2011-12-08  James Robinson  <jam...@chromium.org>
+
+        Add some tests for removing frames from the document while servicing requestAnimationFrame callbacks
+        https://bugs.webkit.org/show_bug.cgi?id=74036
+
+        Reviewed by Adam Barth.
+
+        * fast/animation/request-animation-frame-detach-element-expected.txt: Added.
+        * fast/animation/request-animation-frame-detach-element.html: Added.
+
 2011-12-08  Jacob Goldstein  <jac...@adobe.com>
 
         Convert some fast/regions pixel tests to reftests

Added: trunk/LayoutTests/fast/animation/request-animation-frame-detach-element-expected.txt (0 => 102405)


--- trunk/LayoutTests/fast/animation/request-animation-frame-detach-element-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/animation/request-animation-frame-detach-element-expected.txt	2011-12-09 01:33:41 UTC (rev 102405)
@@ -0,0 +1 @@
+Test passes is there is no crash.  
Property changes on: trunk/LayoutTests/fast/animation/request-animation-frame-detach-element-expected.txt
___________________________________________________________________

Added: svn:eol-style

Added: trunk/LayoutTests/fast/animation/request-animation-frame-detach-element.html (0 => 102405)


--- trunk/LayoutTests/fast/animation/request-animation-frame-detach-element.html	                        (rev 0)
+++ trunk/LayoutTests/fast/animation/request-animation-frame-detach-element.html	2011-12-09 01:33:41 UTC (rev 102405)
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+window._onload_ = function() {
+    var el = document.getElementsByTagName("iframe")[0];
+    window.frames[0].webkitRequestAnimationFrame(function() {
+        el.parentNode.removeChild(el);
+    });
+    window.frames[1].webkitRequestAnimationFrame(function() {
+    });
+
+    if (window.layoutTestController) {
+        window.setTimeout(function() {
+            layoutTestController.display();
+            layoutTestController.notifyDone();
+        }, 50);
+    }
+}
+</script>
+Test passes is there is no crash.
+<iframe></iframe>
+<iframe></iframe>
Property changes on: trunk/LayoutTests/fast/animation/request-animation-frame-detach-element.html
___________________________________________________________________

Added: svn:eol-style

Modified: trunk/Source/WebCore/ChangeLog (102404 => 102405)


--- trunk/Source/WebCore/ChangeLog	2011-12-09 01:31:12 UTC (rev 102404)
+++ trunk/Source/WebCore/ChangeLog	2011-12-09 01:33:41 UTC (rev 102405)
@@ -1,3 +1,28 @@
+2011-12-08  James Robinson  <jam...@chromium.org>
+
+        Improve handling of frame removal during requestAnimationFrame callback invocation
+        https://bugs.webkit.org/show_bug.cgi?id=74036
+
+        Reviewed by Adam Barth.
+
+        See bug for details.
+
+        Test: fast/animation/request-animation-frame-detach-element.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::removedLastRef):
+        (WebCore::Document::detach):
+        * dom/Document.h:
+        * dom/ScriptedAnimationController.cpp:
+        (WebCore::ScriptedAnimationController::~ScriptedAnimationController):
+        (WebCore::ScriptedAnimationController::serviceScriptedAnimations):
+        (WebCore::ScriptedAnimationController::scheduleAnimation):
+        * dom/ScriptedAnimationController.h:
+        (WebCore::ScriptedAnimationController::create):
+        (WebCore::ScriptedAnimationController::clearDocumentPointer):
+        * page/FrameView.cpp:
+        (WebCore::FrameView::serviceScriptedAnimations):
+
 2011-12-08  Yongjun Zhang  <yongjun_zh...@apple.com>
 
         Use bitfield for bool data members in BitmapImage.

Modified: trunk/Source/WebCore/dom/Document.cpp (102404 => 102405)


--- trunk/Source/WebCore/dom/Document.cpp	2011-12-09 01:31:12 UTC (rev 102404)
+++ trunk/Source/WebCore/dom/Document.cpp	2011-12-09 01:33:41 UTC (rev 102405)
@@ -613,7 +613,9 @@
 
 #if ENABLE(REQUEST_ANIMATION_FRAME)
         // FIXME: consider using ActiveDOMObject.
-        m_scriptedAnimationController = nullptr;
+        if (m_scriptedAnimationController)
+            m_scriptedAnimationController->clearDocumentPointer();
+        m_scriptedAnimationController.clear();
 #endif
 
 #ifndef NDEBUG
@@ -1834,7 +1836,9 @@
 
 #if ENABLE(REQUEST_ANIMATION_FRAME)
     // FIXME: consider using ActiveDOMObject.
-    m_scriptedAnimationController = nullptr;
+    if (m_scriptedAnimationController)
+        m_scriptedAnimationController->clearDocumentPointer();
+    m_scriptedAnimationController.clear();
 #endif
 
     RenderObject* render = renderer();

Modified: trunk/Source/WebCore/dom/Document.h (102404 => 102405)


--- trunk/Source/WebCore/dom/Document.h	2011-12-09 01:31:12 UTC (rev 102404)
+++ trunk/Source/WebCore/dom/Document.h	2011-12-09 01:33:41 UTC (rev 102405)
@@ -1441,7 +1441,7 @@
     unsigned m_wheelEventHandlerCount;
 
 #if ENABLE(REQUEST_ANIMATION_FRAME)
-    OwnPtr<ScriptedAnimationController> m_scriptedAnimationController;
+    RefPtr<ScriptedAnimationController> m_scriptedAnimationController;
 #endif
 
     Timer<Document> m_pendingTasksTimer;

Modified: trunk/Source/WebCore/dom/ScriptedAnimationController.cpp (102404 => 102405)


--- trunk/Source/WebCore/dom/ScriptedAnimationController.cpp	2011-12-09 01:31:12 UTC (rev 102404)
+++ trunk/Source/WebCore/dom/ScriptedAnimationController.cpp	2011-12-09 01:33:41 UTC (rev 102405)
@@ -61,6 +61,10 @@
     windowScreenDidChange(displayID);
 }
 
+ScriptedAnimationController::~ScriptedAnimationController()
+{
+}
+
 void ScriptedAnimationController::suspend()
 {
     ++m_suspendCount;
@@ -119,8 +123,17 @@
     // missing any callbacks, we keep iterating through the list of candiate callbacks and firing
     // them until nothing new becomes visible.
     bool firedCallback;
+
+    // Invoking callbacks may detach elements from our document, which clear's the document's
+    // reference to us, so take a defensive reference.
+    RefPtr<ScriptedAnimationController> protector(this);
     do {
         firedCallback = false;
+        // A previous iteration may have detached this Document from the DOM tree.
+        // If so, then we do not need to process any more callbacks.
+        if (!m_document)
+            continue;
+
         // A previous iteration may have invalidated style (or layout).  Update styles for each iteration
         // for now since all we check is the existence of a renderer.
         m_document->updateStyleIfNeeded();
@@ -161,6 +174,9 @@
 
 void ScriptedAnimationController::scheduleAnimation()
 {
+    if (!m_document)
+        return;
+
 #if USE(REQUEST_ANIMATION_FRAME_TIMER)
 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     if (!m_useTimer) {

Modified: trunk/Source/WebCore/dom/ScriptedAnimationController.h (102404 => 102405)


--- trunk/Source/WebCore/dom/ScriptedAnimationController.h	2011-12-09 01:31:12 UTC (rev 102404)
+++ trunk/Source/WebCore/dom/ScriptedAnimationController.h	2011-12-09 01:33:41 UTC (rev 102405)
@@ -35,8 +35,7 @@
 #include "Timer.h"
 #endif
 #include "PlatformScreen.h"
-#include <wtf/Noncopyable.h>
-#include <wtf/PassOwnPtr.h>
+#include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 
@@ -46,17 +45,18 @@
 class Element;
 class RequestAnimationFrameCallback;
 
-class ScriptedAnimationController
+class ScriptedAnimationController : public RefCounted<ScriptedAnimationController>
 #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
-    : public DisplayRefreshMonitorClient
+    , public DisplayRefreshMonitorClient
 #endif
 {
-WTF_MAKE_NONCOPYABLE(ScriptedAnimationController);
 public:
-    static PassOwnPtr<ScriptedAnimationController> create(Document* document, PlatformDisplayID displayID)
+    static PassRefPtr<ScriptedAnimationController> create(Document* document, PlatformDisplayID displayID)
     {
-        return adoptPtr(new ScriptedAnimationController(document, displayID));
+        return adoptRef(new ScriptedAnimationController(document, displayID));
     }
+    ~ScriptedAnimationController();
+    void clearDocumentPointer() { m_document = 0; }
 
     typedef int CallbackId;
 
@@ -70,7 +70,7 @@
     void windowScreenDidChange(PlatformDisplayID);
 
 private:
-    explicit ScriptedAnimationController(Document*, PlatformDisplayID);
+    ScriptedAnimationController(Document*, PlatformDisplayID);
     
     typedef Vector<RefPtr<RequestAnimationFrameCallback> > CallbackList;
     CallbackList m_callbacks;

Modified: trunk/Source/WebCore/page/FrameView.cpp (102404 => 102405)


--- trunk/Source/WebCore/page/FrameView.cpp	2011-12-09 01:31:12 UTC (rev 102404)
+++ trunk/Source/WebCore/page/FrameView.cpp	2011-12-09 01:33:41 UTC (rev 102405)
@@ -2085,8 +2085,13 @@
 #if ENABLE(REQUEST_ANIMATION_FRAME)
 void FrameView::serviceScriptedAnimations(DOMTimeStamp time)
 {
+    Vector<RefPtr<Document> > documents;
+
     for (Frame* frame = m_frame.get(); frame; frame = frame->tree()->traverseNext())
-        frame->document()->serviceScriptedAnimations(time);
+        documents.append(frame->document());
+
+    for (size_t i = 0; i < documents.size(); ++i)
+        documents[i]->serviceScriptedAnimations(time);
 }
 #endif
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to