Bug 1421004 - Break the mDocument reference cycle at Destroy(). r=smaug draft
authorbechen@mozilla.com <bechen@mozilla.com>
Thu, 07 Dec 2017 13:10:51 +0800
changeset 708776 31de6da08d022404a052335cb0900dd6e5e24dd5
parent 705459 56b6cd5befbb7c76384290f2f0d8915231ee27f6
child 743244 815285fd306188acbdc4cd553792364a31735891
push id92445
push userbmo:bechen@mozilla.com
push dateThu, 07 Dec 2017 05:11:23 +0000
reviewerssmaug
bugs1421004
milestone59.0a1
Bug 1421004 - Break the mDocument reference cycle at Destroy(). r=smaug We break the cycle reference between VideoDocument/Plugindocument and MediaDocumentStreamListener when the document be destroyed. MozReview-Commit-ID: Aowla95zMgg
dom/html/MediaDocument.h
dom/html/PluginDocument.cpp
dom/html/VideoDocument.cpp
--- a/dom/html/MediaDocument.h
+++ b/dom/html/MediaDocument.h
@@ -90,16 +90,21 @@ public:
   void SetStreamListener(nsIStreamListener *aListener);
 
   NS_DECL_ISUPPORTS
 
   NS_DECL_NSIREQUESTOBSERVER
 
   NS_DECL_NSISTREAMLISTENER
 
-  RefPtr<MediaDocument>      mDocument;
-  nsCOMPtr<nsIStreamListener>  mNextStream;
+  void DropDocumentRef()
+  {
+    mDocument = nullptr;
+  }
+
+  RefPtr<MediaDocument> mDocument;
+  nsCOMPtr<nsIStreamListener> mNextStream;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif /* mozilla_dom_MediaDocument_h */
--- a/dom/html/PluginDocument.cpp
+++ b/dom/html/PluginDocument.cpp
@@ -43,16 +43,24 @@ public:
   void SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject) override;
   bool CanSavePresentation(nsIRequest *aNewRequest) override;
 
   const nsCString& GetType() const { return mMimeType; }
   Element*         GetPluginContent() { return mPluginContent; }
 
   void StartLayout() { MediaDocument::StartLayout(); }
 
+  virtual void Destroy() override
+  {
+    if (mStreamListener) {
+      mStreamListener->DropDocumentRef();
+    }
+    MediaDocument::Destroy();
+  }
+
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PluginDocument, MediaDocument)
 protected:
   ~PluginDocument() override;
 
   nsresult CreateSyntheticPluginDocument();
 
   nsCOMPtr<Element>                        mPluginContent;
   RefPtr<MediaDocumentStreamListener>    mStreamListener;
--- a/dom/html/VideoDocument.cpp
+++ b/dom/html/VideoDocument.cpp
@@ -23,16 +23,24 @@ public:
                                      nsIChannel*         aChannel,
                                      nsILoadGroup*       aLoadGroup,
                                      nsISupports*        aContainer,
                                      nsIStreamListener** aDocListener,
                                      bool                aReset = true,
                                      nsIContentSink*     aSink = nullptr);
   virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject);
 
+  virtual void Destroy()
+  {
+    if (mStreamListener) {
+      mStreamListener->DropDocumentRef();
+    }
+    MediaDocument::Destroy();
+  }
+
 protected:
 
   // Sets document <title> to reflect the file name and description.
   void UpdateTitle(nsIChannel* aChannel);
 
   nsresult CreateSyntheticVideoDocument(nsIChannel* aChannel,
                                         nsIStreamListener** aListener);