Bug 609814: Unregister SVGDocumentWrapper as XPCOM shutdown observer when we're done with it. r=roc a=blocking-final
authorDaniel Holbert <dholbert@cs.stanford.edu>
Mon, 08 Nov 2010 09:45:18 -0800
changeset 57115 3e6c3cf12c4bc95c2c9d40bef6efeb94ac47d6d1
parent 57114 14e52c423e546b5da12647b2db2f6e7f1f8a060c
child 57116 61700880b8721f9541bdca0488279a3ced363aeb
push id16794
push userdholbert@mozilla.com
push dateMon, 08 Nov 2010 17:53:29 +0000
treeherdermozilla-central@61700880b872 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, blocking-final
bugs609814
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 609814: Unregister SVGDocumentWrapper as XPCOM shutdown observer when we're done with it. r=roc a=blocking-final
modules/libpr0n/src/SVGDocumentWrapper.cpp
modules/libpr0n/src/SVGDocumentWrapper.h
--- a/modules/libpr0n/src/SVGDocumentWrapper.cpp
+++ b/modules/libpr0n/src/SVGDocumentWrapper.cpp
@@ -63,35 +63,40 @@
 
 using namespace mozilla::dom;
 
 namespace mozilla {
 namespace imagelib {
 
 nsIAtom* SVGDocumentWrapper::kSVGAtom = nsnull; // lazily initialized
 
-NS_IMPL_ISUPPORTS3(SVGDocumentWrapper,
+NS_IMPL_ISUPPORTS4(SVGDocumentWrapper,
                    nsIStreamListener,
                    nsIRequestObserver,
-                   nsIObserver)
+                   nsIObserver,
+                   nsISupportsWeakReference)
 
 SVGDocumentWrapper::SVGDocumentWrapper()
- : mIgnoreInvalidation(PR_FALSE)
+  : mIgnoreInvalidation(PR_FALSE),
+    mRegisteredForXPCOMShutdown(PR_FALSE)
 {
   // Lazy-initialize our "svg" atom.  (It'd be nicer to just use nsGkAtoms::svg
   // directly, but we can't access it from here in non-libxul builds.)
   if (!SVGDocumentWrapper::kSVGAtom) {
     SVGDocumentWrapper::kSVGAtom =
       NS_NewPermanentAtom(NS_LITERAL_STRING("svg"));
   }
 }
 
 SVGDocumentWrapper::~SVGDocumentWrapper()
 {
   DestroyViewer();
+  if (mRegisteredForXPCOMShutdown) {
+    UnregisterForXPCOMShutdown();
+  }
 }
 
 void
 SVGDocumentWrapper::DestroyViewer()
 {
   if (mViewer) {
     mViewer->GetDocument()->OnPageHide(PR_FALSE, nsnull);
     mViewer->Close(nsnull);
@@ -371,26 +376,46 @@ SVGDocumentWrapper::SetupViewer(nsIReque
 
   RegisterForXPCOMShutdown();
   return NS_OK;
 }
 
 void
 SVGDocumentWrapper::RegisterForXPCOMShutdown()
 {
+  NS_ABORT_IF_FALSE(!mRegisteredForXPCOMShutdown,
+                    "re-registering for XPCOM shutdown");
   // Listen for xpcom-shutdown so that we can drop references to our
   // helper-document at that point. (Otherwise, we won't get cleaned up
   // until imgLoader::Shutdown, which can happen after the JAR service
   // and RDF service have been unregistered.)
   nsresult rv;
   nsCOMPtr<nsIObserverService> obsSvc = do_GetService(OBSERVER_SVC_CID, &rv);
   if (NS_FAILED(rv) ||
       NS_FAILED(obsSvc->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
-                                    PR_FALSE))) {
+                                    PR_TRUE))) {
     NS_WARNING("Failed to register as observer of XPCOM shutdown");
+  } else {
+    mRegisteredForXPCOMShutdown = PR_TRUE;
+  }
+}
+
+void
+SVGDocumentWrapper::UnregisterForXPCOMShutdown()
+{
+  NS_ABORT_IF_FALSE(mRegisteredForXPCOMShutdown,
+                    "unregistering for XPCOM shutdown w/out being registered");
+
+  nsresult rv;
+  nsCOMPtr<nsIObserverService> obsSvc = do_GetService(OBSERVER_SVC_CID, &rv);
+  if (NS_FAILED(rv) ||
+      NS_FAILED(obsSvc->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) {
+    NS_WARNING("Failed to unregister as observer of XPCOM shutdown");
+  } else {
+    mRegisteredForXPCOMShutdown = PR_FALSE;
   }
 }
 
 void
 SVGDocumentWrapper::FlushLayout()
 {
   nsCOMPtr<nsIPresShell> presShell;
   mViewer->GetPresShell(getter_AddRefs(presShell));
--- a/modules/libpr0n/src/SVGDocumentWrapper.h
+++ b/modules/libpr0n/src/SVGDocumentWrapper.h
@@ -40,16 +40,17 @@
 
 #ifndef mozilla_imagelib_SVGDocumentWrapper_h_
 #define mozilla_imagelib_SVGDocumentWrapper_h_
 
 #include "nsCOMPtr.h"
 #include "nsIStreamListener.h"
 #include "nsIObserver.h"
 #include "nsIDocumentViewer.h"
+#include "nsWeakReference.h"
 
 class nsIAtom;
 class nsIPresShell;
 class nsIRequest;
 class nsIDocumentViewer;
 class nsILoadGroup;
 class nsIFrame;
 class nsIntSize;
@@ -58,17 +59,18 @@ class nsSVGSVGElement;
 #define SVG_MIMETYPE     "image/svg+xml"
 #define OBSERVER_SVC_CID "@mozilla.org/observer-service;1"
 
 
 namespace mozilla {
 namespace imagelib {
 
 class SVGDocumentWrapper : public nsIStreamListener,
-                           public nsIObserver
+                           public nsIObserver,
+                           nsSupportsWeakReference
 {
 public:
   SVGDocumentWrapper();
   ~SVGDocumentWrapper();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIREQUESTOBSERVER
@@ -160,23 +162,25 @@ public:
   void ResetAnimation();
 
 private:
   nsresult SetupViewer(nsIRequest *aRequest,
                        nsIDocumentViewer** aViewer,
                        nsILoadGroup** aLoadGroup);
   void     DestroyViewer();
   void     RegisterForXPCOMShutdown();
+  void     UnregisterForXPCOMShutdown();
 
   void     FlushLayout();
 
   nsCOMPtr<nsIDocumentViewer> mViewer;
   nsCOMPtr<nsILoadGroup>      mLoadGroup;
   nsCOMPtr<nsIStreamListener> mListener;
   PRPackedBool                mIgnoreInvalidation;
+  PRPackedBool                mRegisteredForXPCOMShutdown;
 
   // Lazily-initialized pointer to nsGkAtoms::svg, to make life easier in
   // non-libxul builds, which don't let us reference nsGkAtoms from imagelib.
   static nsIAtom* kSVGAtom;
 };
 
 } // namespace imagelib
 } // namespace mozilla