Bug 635552 - Avoid leaking nsAlertsIconObserver objects by using a weak reference. r=karlt
authorJosh Matthews <josh@joshmatthews.net>
Mon, 21 Feb 2011 01:50:57 -0500
changeset 64443 a3b18039e32fe7ca4b662f73fd6d2e6a5cd9823b
parent 64442 4ede7b9b55bca99cb1bed7948c44dcb2f195e4f0
child 64444 db8e95fbcd39b56b7ae7ad0877e774f9e046949b
push id19344
push usereakhgari@mozilla.com
push dateWed, 30 Mar 2011 17:54:01 +0000
treeherdermozilla-central@422bbd8245a7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt
bugs635552
milestone2.2a1pre
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 635552 - Avoid leaking nsAlertsIconObserver objects by using a weak reference. r=karlt
toolkit/system/gnome/nsAlertsIconListener.cpp
toolkit/system/gnome/nsAlertsIconListener.h
--- a/toolkit/system/gnome/nsAlertsIconListener.cpp
+++ b/toolkit/system/gnome/nsAlertsIconListener.cpp
@@ -70,42 +70,29 @@ static void notify_closed_marshal(GClosu
   NS_ABORT_IF_FALSE(n_param_values >= 1, "No object in params");
 
   nsAlertsIconListener* alert =
     static_cast<nsAlertsIconListener*>(closure->data);
   alert->SendClosed();
   NS_RELEASE(alert);
 }
 
-NS_IMPL_ISUPPORTS3(nsAlertsIconListener, imgIContainerObserver, imgIDecoderObserver, nsIObserver)
+NS_IMPL_ISUPPORTS4(nsAlertsIconListener, imgIContainerObserver,
+                   imgIDecoderObserver, nsIObserver, nsISupportsWeakReference)
 
 nsAlertsIconListener::nsAlertsIconListener()
 : mLoadedFrame(PR_FALSE),
-  mHasQuit(PR_FALSE),
   mNotification(NULL)
 {
-  MOZ_COUNT_CTOR(nsAlertsIconListener);
-
-  nsCOMPtr<nsIObserverService> obsServ =
-      do_GetService("@mozilla.org/observer-service;1");
-  obsServ->AddObserver(this, "quit-application", PR_FALSE);
 }
 
 nsAlertsIconListener::~nsAlertsIconListener()
 {
-  MOZ_COUNT_DTOR(nsAlertsIconListener);
-
   if (mIconRequest)
     mIconRequest->CancelAndForgetObserver(NS_BINDING_ABORTED);
-
-  if (!mHasQuit) {
-    nsCOMPtr<nsIObserverService> obsServ =
-        do_GetService("@mozilla.org/observer-service;1");
-    obsServ->RemoveObserver(this, "quit-application");
-  }
 }
 
 NS_IMETHODIMP
 nsAlertsIconListener::OnStartRequest(imgIRequest* aRequest)
 {
   return NS_OK;
 }
 
@@ -302,17 +289,16 @@ NS_IMETHODIMP
 nsAlertsIconListener::Observe(nsISupports *aSubject, const char *aTopic,
                               const PRUnichar *aData) {
   // We need to close any open notifications upon application exit, otherwise
   // we will leak since libnotify holds a ref for us.
   if (!nsCRT::strcmp(aTopic, "quit-application") && mNotification) {
     g_signal_handler_disconnect(mNotification, mClosureHandler);
     g_object_unref(mNotification);
     mNotification = NULL;
-    mHasQuit = PR_TRUE;
     Release(); // equivalent to NS_RELEASE(this)
   }
   return NS_OK;
 }
 
 nsresult
 nsAlertsIconListener::InitAlertAsync(const nsAString & aImageUrl,
                                      const nsAString & aAlertTitle, 
@@ -359,16 +345,21 @@ nsAlertsIconListener::InitAlertAsync(con
       g_list_foreach(server_caps, (GFunc)g_free, NULL);
       g_list_free(server_caps);
     }
   }
 
   if (!gHasActions && aAlertTextClickable)
     return NS_ERROR_FAILURE; // No good, fallback to XUL
 
+  nsCOMPtr<nsIObserverService> obsServ =
+      do_GetService("@mozilla.org/observer-service;1");
+  if (obsServ)
+    obsServ->AddObserver(this, "quit-application", PR_TRUE);
+
   // Workaround for a libnotify bug - blank titles aren't dealt with
   // properly so we use a space
   if (aAlertTitle.IsEmpty()) {
     mAlertTitle = NS_LITERAL_CSTRING(" ");
   } else {
     mAlertTitle = NS_ConvertUTF16toUTF8(aAlertTitle);
   }
 
--- a/toolkit/system/gnome/nsAlertsIconListener.h
+++ b/toolkit/system/gnome/nsAlertsIconListener.h
@@ -37,24 +37,26 @@
 
 #ifndef nsAlertsIconListener_h__
 #define nsAlertsIconListener_h__
 
 #include "nsCOMPtr.h"
 #include "imgIDecoderObserver.h"
 #include "nsStringAPI.h"
 #include "nsIObserver.h"
+#include "nsWeakReference.h"
 
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <libnotify/notify.h>
 
 class imgIRequest;
 
 class nsAlertsIconListener : public imgIDecoderObserver,
-                             public nsIObserver
+                             public nsIObserver,
+                             public nsSupportsWeakReference
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IMGICONTAINEROBSERVER
   NS_DECL_IMGIDECODEROBSERVER
   NS_DECL_NSIOBSERVER
 
   nsAlertsIconListener();
@@ -75,17 +77,16 @@ protected:
   nsCString mAlertTitle;
   nsCString mAlertText;
 
   nsCOMPtr<nsIObserver> mAlertListener;
   nsString mAlertCookie;
 
   PRPackedBool mLoadedFrame;
   PRPackedBool mAlertHasAction;
-  PRPackedBool mHasQuit;
 
   NotifyNotification* mNotification;
   gulong mClosureHandler;
 
   nsresult StartRequest(const nsAString & aImageUrl);
   nsresult ShowAlert(GdkPixbuf* aPixbuf);
 };