[evolution-data-server] Follow-up fixes of bug #627871



commit 9292a241289612902ade970db17bd9c3281aed23
Author: Milan Crha <mcrha redhat com>
Date:   Tue Aug 31 16:35:12 2010 +0200

    Follow-up fixes of bug #627871
    
    - memory leaks in ENameSelector (e-addressbook-factory didn't close)
    - unsubscribe from NameOwnerChanged and closed GDBus signals (both ECal and EBook)
    - report about "factory vanished" only with active ECal/EBook
    - unwrap_gerror on async open of ECal

 addressbook/libebook/e-book.c            |   20 ++++++++++++++++++--
 calendar/libecal/e-cal.c                 |   23 +++++++++++++++++++++--
 libedataserverui/e-name-selector-entry.c |   10 ++++++++++
 libedataserverui/e-name-selector-list.c  |    2 --
 libedataserverui/e-name-selector.c       |    2 ++
 5 files changed, 51 insertions(+), 6 deletions(-)
---
diff --git a/addressbook/libebook/e-book.c b/addressbook/libebook/e-book.c
index 537dddc..727acf4 100644
--- a/addressbook/libebook/e-book.c
+++ b/addressbook/libebook/e-book.c
@@ -80,6 +80,7 @@ struct _EBookPrivate {
 	gboolean cap_queried;
 };
 
+static guint active_books = 0, book_connection_closed_id = 0;
 static EGdbusBookFactory *book_factory_proxy = NULL;
 static GStaticRecMutex book_factory_proxy_lock = G_STATIC_REC_MUTEX_INIT;
 #define LOCK_FACTORY()   g_static_rec_mutex_lock (&book_factory_proxy_lock)
@@ -187,6 +188,10 @@ e_book_finalize (GObject *object)
 
 	if (G_OBJECT_CLASS (e_book_parent_class)->finalize)
 		G_OBJECT_CLASS (e_book_parent_class)->finalize (object);
+
+	LOCK_FACTORY ();
+	active_books--;
+	UNLOCK_FACTORY ();
 }
 
 static void
@@ -243,6 +248,10 @@ e_book_init (EBook *book)
 {
 	EBookPrivate *priv = E_BOOK_GET_PRIVATE (book);
 
+	LOCK_FACTORY ();
+	active_books++;
+	UNLOCK_FACTORY ();
+
 	priv->gdbus_book = NULL;
 	priv->source = NULL;
 	priv->uri = NULL;
@@ -260,6 +269,13 @@ book_factory_proxy_closed_cb (GDBusConnection *connection, gboolean remote_peer_
 	GError *err = NULL;
 
 	LOCK_FACTORY ();
+
+	if (book_connection_closed_id) {
+		g_dbus_connection_signal_unsubscribe (connection, book_connection_closed_id);
+		book_connection_closed_id = 0;
+		g_signal_handlers_disconnect_by_func (connection, book_factory_proxy_closed_cb, NULL);
+	}
+
 	if (book_factory_proxy) {
 		g_object_unref (book_factory_proxy);
 		book_factory_proxy = NULL;
@@ -271,7 +287,7 @@ book_factory_proxy_closed_cb (GDBusConnection *connection, gboolean remote_peer_
 	if (err) {
 		g_debug ("GDBus connection is closed%s: %s", remote_peer_vanished ? ", remote peer vanished" : "", err->message);
 		g_error_free (err);
-	} else {
+	} else if (active_books) {
 		g_debug ("GDBus connection is closed%s", remote_peer_vanished ? ", remote peer vanished" : "");
 	}
 
@@ -313,7 +329,7 @@ e_book_activate (GError **error)
 
 	connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (book_factory_proxy));
 	g_dbus_connection_set_exit_on_close (connection, FALSE);
-	g_dbus_connection_signal_subscribe (connection,
+	book_connection_closed_id = g_dbus_connection_signal_subscribe (connection,
 		NULL,						/* sender */
 		"org.freedesktop.DBus",				/* interface */
 		"NameOwnerChanged",				/* member */
diff --git a/calendar/libecal/e-cal.c b/calendar/libecal/e-cal.c
index da89e7b..2559354 100644
--- a/calendar/libecal/e-cal.c
+++ b/calendar/libecal/e-cal.c
@@ -56,6 +56,7 @@
 #include "e-gdbus-egdbuscal.h"
 #include "e-gdbus-egdbuscalview.h"
 
+static guint active_cals = 0, cal_connection_closed_id = 0;
 static EGdbusCalFactory *cal_factory_proxy = NULL;
 static GStaticRecMutex cal_factory_proxy_lock = G_STATIC_REC_MUTEX_INIT;
 #define LOCK_FACTORY()   g_static_rec_mutex_lock   (&cal_factory_proxy_lock)
@@ -406,6 +407,10 @@ e_cal_init (ECal *ecal)
 {
 	ECalPrivate *priv;
 
+	LOCK_FACTORY ();
+	active_cals++;
+	UNLOCK_FACTORY ();
+
 	ecal->priv = priv = E_CAL_GET_PRIVATE (ecal);
 
 	priv->load_state = E_CAL_LOAD_NOT_LOADED;
@@ -559,6 +564,10 @@ e_cal_finalize (GObject *object)
 	g_static_rec_mutex_free (&priv->cache_lock);
 
 	(* G_OBJECT_CLASS (parent_class)->finalize) (object);
+
+	LOCK_FACTORY ();
+	active_cals--;
+	UNLOCK_FACTORY ();
 }
 
 /* Class initialization function for the calendar ecal */
@@ -637,6 +646,13 @@ cal_factory_proxy_closed_cb (GDBusConnection *connection, gboolean remote_peer_v
 	GError *err = NULL;
 
 	LOCK_FACTORY ();
+
+	if (cal_connection_closed_id) {
+		g_dbus_connection_signal_unsubscribe (connection, cal_connection_closed_id);
+		cal_connection_closed_id = 0;
+		g_signal_handlers_disconnect_by_func (connection, cal_factory_proxy_closed_cb, NULL);
+	}
+
 	if (cal_factory_proxy) {
 		g_object_unref (cal_factory_proxy);
 		cal_factory_proxy = NULL;
@@ -650,7 +666,7 @@ cal_factory_proxy_closed_cb (GDBusConnection *connection, gboolean remote_peer_v
 	if (err) {
 		g_debug ("GDBus connection is closed%s: %s", remote_peer_vanished ? ", remote peer vanished" : "", err->message);
 		g_error_free (err);
-	} else {
+	} else if (active_cals) {
 		g_debug ("GDBus connection is closed%s", remote_peer_vanished ? ", remote peer vanished" : "");
 	}
 
@@ -692,7 +708,7 @@ e_cal_activate (GError **error)
 
 	connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (cal_factory_proxy));
 	g_dbus_connection_set_exit_on_close (connection, FALSE);
-	g_dbus_connection_signal_subscribe (connection,
+	cal_connection_closed_id = g_dbus_connection_signal_subscribe (connection,
 		NULL,						/* sender */
 		"org.freedesktop.DBus",				/* interface */
 		"NameOwnerChanged",				/* member */
@@ -1155,6 +1171,8 @@ async_open_ready_cb (EGdbusCal *gdbus_cal, GAsyncResult *res, ECal *ecal)
 
 	e_gdbus_cal_call_open_finish (gdbus_cal, res, &error);
 
+	unwrap_gerror (&error);
+
 	async_open_report_result (ecal, error);
 
 	if (error)
@@ -1279,6 +1297,7 @@ open_calendar (ECal *ecal, gboolean only_if_exists, GError **error,
 				g_error_free (err);
 		}
 	} else {
+		unwrap_gerror (error);
 		priv->load_state = E_CAL_LOAD_NOT_LOADED;
 	}
 
diff --git a/libedataserverui/e-name-selector-entry.c b/libedataserverui/e-name-selector-entry.c
index 1445cb0..70095cf 100644
--- a/libedataserverui/e-name-selector-entry.c
+++ b/libedataserverui/e-name-selector-entry.c
@@ -121,6 +121,16 @@ name_selector_entry_dispose (GObject *object)
 		priv->destination_store = NULL;
 	}
 
+	if (priv->email_generator) {
+		g_object_unref (priv->email_generator);
+		priv->email_generator = NULL;
+	}
+
+	if (priv->contact_store) {
+		g_object_unref (priv->contact_store);
+		priv->contact_store = NULL;
+	}
+
 	g_slist_foreach (priv->user_query_fields, (GFunc)g_free, NULL);
 	g_slist_free (priv->user_query_fields);
 	priv->user_query_fields = NULL;
diff --git a/libedataserverui/e-name-selector-list.c b/libedataserverui/e-name-selector-list.c
index f3be29c..666dd1e 100644
--- a/libedataserverui/e-name-selector-list.c
+++ b/libedataserverui/e-name-selector-list.c
@@ -47,7 +47,6 @@ struct _ENameSelectorListPrivate {
 	GtkWindow *popup;
 	GtkWidget *tree_view;
 	GtkWidget *menu;
-	EDestinationStore *store;
 	gint rows;
 };
 
@@ -631,7 +630,6 @@ e_name_selector_list_init (ENameSelectorList *list)
 
 	list->priv = E_NAME_SELECTOR_LIST_GET_PRIVATE (list);
 
-	list->priv->store = e_destination_store_new ();
 	list->priv->menu = NULL;
 
 	entry = E_NAME_SELECTOR_ENTRY (list);
diff --git a/libedataserverui/e-name-selector.c b/libedataserverui/e-name-selector.c
index 04111fa..c537ada 100644
--- a/libedataserverui/e-name-selector.c
+++ b/libedataserverui/e-name-selector.c
@@ -212,9 +212,11 @@ name_selector_dispose (GObject *object)
 		section = &g_array_index (priv->sections, Section, ii);
 		if (section->entry)
 			g_object_weak_unref (G_OBJECT (section->entry), reset_pointer_cb, object);
+		g_free (section->name);
 	}
 
 	g_array_set_size (priv->source_books, 0);
+	g_array_set_size (priv->sections, 0);
 
 	/* Chain up to parent's dispose() method. */
 	G_OBJECT_CLASS (e_name_selector_parent_class)->dispose (object);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]