Bug 529664. Disconnect alert listener on shutdown. r=roc,karlt
authorMichael Ventnor <ventnor.bugzilla@gmail.com>
Thu, 14 Jan 2010 15:30:04 +1300
changeset 37171 9aa39a24d7fc7e08379b741f8a16b1ad6c0c39d4
parent 37170 3c268b20d526a3237a3cc371d49f2f625e2ce7fa
child 37172 340b2f20f7195dd8a8c485402d7bd2e965bd51ca
push id11157
push userrocallahan@mozilla.com
push dateThu, 14 Jan 2010 02:30:30 +0000
treeherdermozilla-central@ad1a239a0b13 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, karlt
bugs529664
milestone1.9.3a1pre
Bug 529664. Disconnect alert listener on shutdown. r=roc,karlt
toolkit/system/gnome/nsAlertsIconListener.cpp
toolkit/system/gnome/nsAlertsIconListener.h
--- a/toolkit/system/gnome/nsAlertsIconListener.cpp
+++ b/toolkit/system/gnome/nsAlertsIconListener.cpp
@@ -59,19 +59,16 @@ static void notify_closed_marshal(GClosu
                                   GValue* return_value,
                                   guint n_param_values,
                                   const GValue* param_values,
                                   gpointer invocation_hint,
                                   gpointer marshal_data)
 {
   NS_ABORT_IF_FALSE(n_param_values >= 1, "No object in params");
 
-  gpointer notification = g_value_peek_pointer(param_values);
-  g_object_unref(notification);
-
   nsAlertsIconListener* alert =
     static_cast<nsAlertsIconListener*>(closure->data);
   alert->SendClosed();
   NS_RELEASE(alert);
 }
 
 NS_IMPL_ISUPPORTS3(nsAlertsIconListener, imgIContainerObserver, imgIDecoderObserver, nsIObserver)
 
@@ -238,17 +235,17 @@ nsAlertsIconListener::ShowAlert(GdkPixbu
   }
 
   // Fedora 10 calls NotifyNotification "closed" signal handlers with a
   // different signature, so a marshaller is used instead of a C callback to
   // get the user_data (this) in a parseable format.  |closure| is created
   // with a floating reference, which gets sunk by g_signal_connect_closure().
   GClosure* closure = g_closure_new_simple(sizeof(GClosure), this);
   g_closure_set_marshal(closure, notify_closed_marshal);
-  g_signal_connect_closure(mNotification, "closed", closure, FALSE);
+  mClosureHandler = g_signal_connect_closure(mNotification, "closed", closure, FALSE);
   gboolean result = notify_notification_show(mNotification, NULL);
 
   return result ? NS_OK : NS_ERROR_FAILURE;
 }
 
 nsresult
 nsAlertsIconListener::StartRequest(const nsAString & aImageUrl)
 {
@@ -277,29 +274,35 @@ nsAlertsIconListener::SendCallback()
 {
   if (mAlertListener)
     mAlertListener->Observe(NULL, "alertclickcallback", mAlertCookie.get());
 }
 
 void
 nsAlertsIconListener::SendClosed()
 {
-  mNotification = NULL;
+  if (mNotification) {
+    g_object_unref(mNotification);
+    mNotification = NULL;
+  }
   if (mAlertListener)
     mAlertListener->Observe(NULL, "alertfinished", mAlertCookie.get());
 }
 
 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) {
-    notify_notification_close(mNotification, NULL);
+    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, 
                                      const nsAString & aAlertText,
--- a/toolkit/system/gnome/nsAlertsIconListener.h
+++ b/toolkit/system/gnome/nsAlertsIconListener.h
@@ -78,14 +78,15 @@ protected:
   nsCOMPtr<nsIObserver> mAlertListener;
   nsString mAlertCookie;
 
   PRPackedBool mLoadedFrame;
   PRPackedBool mAlertHasAction;
   PRPackedBool mHasQuit;
 
   NotifyNotification* mNotification;
+  gulong mClosureHandler;
 
   nsresult StartRequest(const nsAString & aImageUrl);
   nsresult ShowAlert(GdkPixbuf* aPixbuf);
 };
 
 #endif