Title: [104874] trunk/Source/WebCore
Revision
104874
Author
benja...@webkit.org
Date
2012-01-12 16:19:10 -0800 (Thu, 12 Jan 2012)

Log Message

A Frame with frame flattening can be stuck in a state in which performPostLayoutTasks() is never executed
https://bugs.webkit.org/show_bug.cgi?id=76154

Patch by Benjamin Poulain <bpoul...@apple.com> on 2012-01-12
Reviewed by Beth Dakin.

In a frame with inSubframeLayoutWithFrameFlattening == true, if
-m_hasPendingPostLayoutTasks == true
-FrameView::unscheduleRelayout() is executed
-->the timer m_postLayoutTasksTimer is stopped
-->no timer is scheduled due to m_hasPendingPostLayoutTasks == true && inSubframeLayoutWithFrameFlattening == true

This patch revert the handling of the postLayoutTasks to its state prior to r66552.

The timer itself is used as the only state to know if post layout tasks are scheduled.

For the case without frame flattening:
-Prior to this patch, when FrameView::unscheduleRelayout() was executed, the postLayoutTasksTimer was killed,
and the post layout tasks would be executed during the next layout().
-After this patch, the post layout tasks stay scheduled and are executed on the next event loop if layout()
was not invoked before.

* page/FrameView.cpp:
(WebCore::FrameView::FrameView):
(WebCore::FrameView::~FrameView):
(WebCore::FrameView::reset):
(WebCore::FrameView::layout):
(WebCore::FrameView::unscheduleRelayout):
(WebCore::FrameView::flushAnyPendingPostLayoutTasks):
(WebCore::FrameView::performPostLayoutTasks):
* page/FrameView.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (104873 => 104874)


--- trunk/Source/WebCore/ChangeLog	2012-01-12 23:59:53 UTC (rev 104873)
+++ trunk/Source/WebCore/ChangeLog	2012-01-13 00:19:10 UTC (rev 104874)
@@ -1,3 +1,36 @@
+2012-01-12  Benjamin Poulain  <bpoul...@apple.com>
+
+        A Frame with frame flattening can be stuck in a state in which performPostLayoutTasks() is never executed
+        https://bugs.webkit.org/show_bug.cgi?id=76154
+
+        Reviewed by Beth Dakin.
+
+        In a frame with inSubframeLayoutWithFrameFlattening == true, if
+        -m_hasPendingPostLayoutTasks == true
+        -FrameView::unscheduleRelayout() is executed
+        -->the timer m_postLayoutTasksTimer is stopped
+        -->no timer is scheduled due to m_hasPendingPostLayoutTasks == true && inSubframeLayoutWithFrameFlattening == true
+
+        This patch revert the handling of the postLayoutTasks to its state prior to r66552.
+
+        The timer itself is used as the only state to know if post layout tasks are scheduled.
+
+        For the case without frame flattening:
+        -Prior to this patch, when FrameView::unscheduleRelayout() was executed, the postLayoutTasksTimer was killed,
+        and the post layout tasks would be executed during the next layout().
+        -After this patch, the post layout tasks stay scheduled and are executed on the next event loop if layout()
+        was not invoked before.
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::FrameView):
+        (WebCore::FrameView::~FrameView):
+        (WebCore::FrameView::reset):
+        (WebCore::FrameView::layout):
+        (WebCore::FrameView::unscheduleRelayout):
+        (WebCore::FrameView::flushAnyPendingPostLayoutTasks):
+        (WebCore::FrameView::performPostLayoutTasks):
+        * page/FrameView.h:
+
 2012-01-12  Yongjun Zhang  <yongjun_zh...@apple.com>
 
         Reviewed by Benjamin Poulain.

Modified: trunk/Source/WebCore/page/FrameView.cpp (104873 => 104874)


--- trunk/Source/WebCore/page/FrameView.cpp	2012-01-12 23:59:53 UTC (rev 104873)
+++ trunk/Source/WebCore/page/FrameView.cpp	2012-01-13 00:19:10 UTC (rev 104874)
@@ -134,7 +134,6 @@
 #if ENABLE(SVG)
     , m_inLayoutParentView(false)
 #endif
-    , m_hasPendingPostLayoutTasks(false)
     , m_inSynchronousPostLayout(false)
     , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
     , m_isTransparent(false)
@@ -186,7 +185,7 @@
 
 FrameView::~FrameView()
 {
-    if (m_hasPendingPostLayoutTasks) {
+    if (m_postLayoutTasksTimer.isActive()) {
         m_postLayoutTasksTimer.stop();
         m_actionScheduler->clear();
     }
@@ -232,7 +231,6 @@
     m_layoutSchedulingEnabled = true;
     m_inLayout = false;
     m_inSynchronousPostLayout = false;
-    m_hasPendingPostLayoutTasks = false;
     m_layoutCount = 0;
     m_nestedLayoutCount = 0;
     m_postLayoutTasksTimer.stop();
@@ -994,11 +992,10 @@
     {
         TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
 
-        if (!m_nestedLayoutCount && !m_inSynchronousPostLayout && m_hasPendingPostLayoutTasks && !inSubframeLayoutWithFrameFlattening) {
+        if (!m_nestedLayoutCount && !m_inSynchronousPostLayout && m_postLayoutTasksTimer.isActive() && !inSubframeLayoutWithFrameFlattening) {
             // This is a new top-level layout. If there are any remaining tasks from the previous
             // layout, finish them now.
             m_inSynchronousPostLayout = true;
-            m_postLayoutTasksTimer.stop();
             performPostLayoutTasks();
             m_inSynchronousPostLayout = false;
         }
@@ -1170,7 +1167,7 @@
         updateOverflowStatus(layoutWidth() < contentsWidth(),
                              layoutHeight() < contentsHeight());
 
-    if (!m_hasPendingPostLayoutTasks) {
+    if (!m_postLayoutTasksTimer.isActive()) {
         if (!m_inSynchronousPostLayout) {
             if (inSubframeLayoutWithFrameFlattening) {
                 if (RenderView* root = rootRenderer(this))
@@ -1183,12 +1180,11 @@
             }
         }
         
-        if (!m_hasPendingPostLayoutTasks && (needsLayout() || m_inSynchronousPostLayout || inSubframeLayoutWithFrameFlattening)) {
+        if (!m_postLayoutTasksTimer.isActive() && (needsLayout() || m_inSynchronousPostLayout || inSubframeLayoutWithFrameFlattening)) {
             // If we need layout or are already in a synchronous call to postLayoutTasks(), 
             // defer widget updates and event dispatch until after we return. postLayoutTasks()
             // can make us need to update again, and we can get stuck in a nasty cycle unless
             // we call it through the timer here.
-            m_hasPendingPostLayoutTasks = true;
             m_postLayoutTasksTimer.startOneShot(0);
             if (needsLayout()) {
                 m_actionScheduler->pause();
@@ -2093,8 +2089,6 @@
 
 void FrameView::unscheduleRelayout()
 {
-    m_postLayoutTasksTimer.stop();
-
     if (!m_layoutTimer.isActive())
         return;
 
@@ -2276,16 +2270,15 @@
 
 void FrameView::flushAnyPendingPostLayoutTasks()
 {
-    if (!m_hasPendingPostLayoutTasks)
+    if (!m_postLayoutTasksTimer.isActive())
         return;
 
-    m_postLayoutTasksTimer.stop();
     performPostLayoutTasks();
 }
 
 void FrameView::performPostLayoutTasks()
 {
-    m_hasPendingPostLayoutTasks = false;
+    m_postLayoutTasksTimer.stop();
 
     m_frame->selection()->setCaretRectNeedsUpdate();
     m_frame->selection()->updateAppearance();

Modified: trunk/Source/WebCore/page/FrameView.h (104873 => 104874)


--- trunk/Source/WebCore/page/FrameView.h	2012-01-12 23:59:53 UTC (rev 104873)
+++ trunk/Source/WebCore/page/FrameView.h	2012-01-13 00:19:10 UTC (rev 104874)
@@ -425,7 +425,6 @@
 #if ENABLE(SVG)
     bool m_inLayoutParentView;
 #endif
-    bool m_hasPendingPostLayoutTasks;
     bool m_inSynchronousPostLayout;
     int m_layoutCount;
     unsigned m_nestedLayoutCount;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to