Fix crash due to RemoteLayerTreeDisplayRefreshMonitor outliving RemoteLayerTreeDrawin...
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Jul 2015 00:23:05 +0000 (00:23 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Jul 2015 00:23:05 +0000 (00:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=147124
<rdar://problem/21582858>

Reviewed by Simon Fraser.

Refactors RemoteLayerTreeDisplayRefreshMonitor to use a weak pointer rather than a reference
to its RemoteLayerTreeDrawingArea, since the drawing area may be deallocated before the monitor
in some rare cases. This rarely caused pages using requestAnimationFrame to crash on iOS. However,
this should not be the case: logically, a RemoteLayerTreeDrawingArea should always outlive its
refresh monitors. Refer to https://bugs.webkit.org/show_bug.cgi?id=147128 for more details.

* WebProcess/WebPage/Cocoa/RemoteLayerTreeDisplayRefreshMonitor.h:
* WebProcess/WebPage/Cocoa/RemoteLayerTreeDisplayRefreshMonitor.mm:
(WebKit::RemoteLayerTreeDisplayRefreshMonitor::RemoteLayerTreeDisplayRefreshMonitor):
(WebKit::RemoteLayerTreeDisplayRefreshMonitor::~RemoteLayerTreeDisplayRefreshMonitor): On destruction, checks
    first to see whether or not the drawing area has been deallocated before telling it to update its monitors.
(WebKit::RemoteLayerTreeDisplayRefreshMonitor::requestRefreshCallback):
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
(WebKit::RemoteLayerTreeDrawingArea::createWeakPtr): Creates and returns a new weak pointer to itself.
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
(WebKit::RemoteLayerTreeDrawingArea::RemoteLayerTreeDrawingArea):

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

Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/WebPage/Cocoa/RemoteLayerTreeDisplayRefreshMonitor.h
Source/WebKit2/WebProcess/WebPage/Cocoa/RemoteLayerTreeDisplayRefreshMonitor.mm
Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h
Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm

index f338fc28b8ee4b0a155432e29a4429f218cb2985..604c726eefff104571c0b467bb0427ed11b8e13b 100644 (file)
@@ -1,3 +1,28 @@
+2015-07-20  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Fix crash due to RemoteLayerTreeDisplayRefreshMonitor outliving RemoteLayerTreeDrawingArea
+        https://bugs.webkit.org/show_bug.cgi?id=147124
+        <rdar://problem/21582858>
+
+        Reviewed by Simon Fraser.
+
+        Refactors RemoteLayerTreeDisplayRefreshMonitor to use a weak pointer rather than a reference
+        to its RemoteLayerTreeDrawingArea, since the drawing area may be deallocated before the monitor
+        in some rare cases. This rarely caused pages using requestAnimationFrame to crash on iOS. However,
+        this should not be the case: logically, a RemoteLayerTreeDrawingArea should always outlive its
+        refresh monitors. Refer to https://bugs.webkit.org/show_bug.cgi?id=147128 for more details.
+
+        * WebProcess/WebPage/Cocoa/RemoteLayerTreeDisplayRefreshMonitor.h:
+        * WebProcess/WebPage/Cocoa/RemoteLayerTreeDisplayRefreshMonitor.mm:
+        (WebKit::RemoteLayerTreeDisplayRefreshMonitor::RemoteLayerTreeDisplayRefreshMonitor):
+        (WebKit::RemoteLayerTreeDisplayRefreshMonitor::~RemoteLayerTreeDisplayRefreshMonitor): On destruction, checks
+            first to see whether or not the drawing area has been deallocated before telling it to update its monitors.
+        (WebKit::RemoteLayerTreeDisplayRefreshMonitor::requestRefreshCallback):
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
+        (WebKit::RemoteLayerTreeDrawingArea::createWeakPtr): Creates and returns a new weak pointer to itself.
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
+        (WebKit::RemoteLayerTreeDrawingArea::RemoteLayerTreeDrawingArea):
+
 2015-07-20  Alex Christensen  <achristensen@webkit.org>
 
         [Content Extensions] Cache actions with domains that match everything
index 31f7c24f1c6a8b54510040e820a0b0e131b9b48d..9069d920aea904ca58b563d70a63afcd6fba08b2 100644 (file)
@@ -49,7 +49,7 @@ public:
 private:
     explicit RemoteLayerTreeDisplayRefreshMonitor(PlatformDisplayID, RemoteLayerTreeDrawingArea&);
 
-    RemoteLayerTreeDrawingArea& m_drawingArea;
+    WeakPtr<RemoteLayerTreeDrawingArea> m_drawingArea;
 };
 
 }
index e4c64c4981819a97fcac552466d24ae4902d7bcb..bf2f724bca8920ed1bd62f08cb4274a76c3948c6 100644 (file)
@@ -36,22 +36,23 @@ namespace WebKit {
 
 RemoteLayerTreeDisplayRefreshMonitor::RemoteLayerTreeDisplayRefreshMonitor(PlatformDisplayID displayID, RemoteLayerTreeDrawingArea& drawingArea)
     : DisplayRefreshMonitor(displayID)
-    , m_drawingArea(drawingArea)
+    , m_drawingArea(drawingArea.createWeakPtr())
 {
 }
 
 RemoteLayerTreeDisplayRefreshMonitor::~RemoteLayerTreeDisplayRefreshMonitor()
 {
-    m_drawingArea.willDestroyDisplayRefreshMonitor(this);
+    if (m_drawingArea)
+        m_drawingArea->willDestroyDisplayRefreshMonitor(this);
 }
 
 bool RemoteLayerTreeDisplayRefreshMonitor::requestRefreshCallback()
 {
-    if (!isActive())
+    if (!m_drawingArea || !isActive())
         return false;
 
     if (!isScheduled())
-        static_cast<DrawingArea&>(m_drawingArea).scheduleCompositingLayerFlush();
+        static_cast<DrawingArea&>(*m_drawingArea.get()).scheduleCompositingLayerFlush();
 
     setIsActive(true);
     setIsScheduled(true);
index 0688a039e9a221327de572471fa888d2a0af23a8..424b92b151011da9c8095f459a15f9951e4235a8 100644 (file)
@@ -56,6 +56,8 @@ public:
 
     uint64_t nextTransactionID() const { return m_currentTransactionID + 1; }
 
+    WeakPtr<RemoteLayerTreeDrawingArea> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
+    
 private:
     // DrawingArea
     virtual void setNeedsDisplay() override;
@@ -166,6 +168,8 @@ private:
 
     WebCore::GraphicsLayer* m_contentLayer;
     WebCore::GraphicsLayer* m_viewOverlayRootLayer;
+    
+    WeakPtrFactory<RemoteLayerTreeDrawingArea> m_weakPtrFactory;
 };
 
 } // namespace WebKit
index 8212f5f8e3d8b0483d28898ccc8449509ae32b93..a2cef58b0a10794fc1f47d528d2cf6fbacb70c99 100644 (file)
@@ -72,6 +72,7 @@ RemoteLayerTreeDrawingArea::RemoteLayerTreeDrawingArea(WebPage& webPage, const W
     , m_currentTransactionID(0)
     , m_contentLayer(nullptr)
     , m_viewOverlayRootLayer(nullptr)
+    , m_weakPtrFactory(this)
 {
     webPage.corePage()->settings().setForceCompositingMode(true);
 #if PLATFORM(IOS)