Bug 1503082 - Clear CanvasShutdownObserver::mCanvas when the canvas goes away. r=nical, a=RyanVM
authorAndrew McCreight <continuation@gmail.com>
Mon, 05 Nov 2018 21:35:44 -0500
changeset 501088 522a5434e0a42890c5292c0228eea366e7dabafd
parent 501087 74833aee1389ae0174a08831d53b0dc851e06bd7
child 501089 f65ddbf6c00545fcf8f56df06ee2a7e3811e5faf
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical, RyanVM
bugs1503082
milestone64.0
Bug 1503082 - Clear CanvasShutdownObserver::mCanvas when the canvas goes away. r=nical, a=RyanVM It is possible for the CanvasRenderingContext2D to be destroyed while we're in the middle of the call to nsObserverService::NotifyObservers() for shutdown. This leaves the shutdown observer with a dangling pointer to the canvas, so this patch explicitly clears the pointer when the context goes away. Differential Revision: https://phabricator.services.mozilla.com/D10777
dom/canvas/CanvasRenderingContext2D.cpp
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -775,16 +775,25 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Ca
 
 class CanvasShutdownObserver final : public nsIObserver
 {
 public:
   explicit CanvasShutdownObserver(CanvasRenderingContext2D* aCanvas)
   : mCanvas(aCanvas)
   {}
 
+  void OnShutdown() {
+    if (!mCanvas) {
+      return;
+    }
+
+    mCanvas = nullptr;
+    nsContentUtils::UnregisterShutdownObserver(this);
+  }
+
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 private:
   ~CanvasShutdownObserver() {}
 
   CanvasRenderingContext2D* mCanvas;
 };
 
@@ -792,17 +801,17 @@ NS_IMPL_ISUPPORTS(CanvasShutdownObserver
 
 NS_IMETHODIMP
 CanvasShutdownObserver::Observe(nsISupports* aSubject,
                                 const char* aTopic,
                                 const char16_t* aData)
 {
   if (mCanvas && strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
     mCanvas->OnShutdown();
-    nsContentUtils::UnregisterShutdownObserver(this);
+    OnShutdown();
   }
 
   return NS_OK;
 }
 
 class CanvasDrawObserver
 {
 public:
@@ -1185,17 +1194,17 @@ CanvasRenderingContext2D::OnShutdown()
     provider->OnShutdown();
   }
 }
 
 void
 CanvasRenderingContext2D::RemoveShutdownObserver()
 {
   if (mShutdownObserver) {
-    nsContentUtils::UnregisterShutdownObserver(mShutdownObserver);
+    mShutdownObserver->OnShutdown();
     mShutdownObserver = nullptr;
   }
 }
 
 void
 CanvasRenderingContext2D::SetStyleFromString(const nsAString& aStr,
                                              Style aWhichStyle)
 {