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
--- 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);