[evolution-data-server] In the factories, don't double-free some memory (and crash) when the DBus service name owner changes



commit e17550793f65bbcd5c233391c7331ff3612324f8
Author: Travis Reitter <treitter gmail com>
Date:   Tue Dec 15 11:39:52 2009 -0800

    In the factories, don't double-free some memory (and crash) when the DBus service name owner changes. This would happen when a client application was launched twice rapidly (and in related cases), usually putting the client in a bad state.

 addressbook/libedata-book/e-data-book-factory.c |   11 +++++++----
 calendar/libedata-cal/e-data-cal-factory.c      |   12 +++++++-----
 2 files changed, 14 insertions(+), 9 deletions(-)
---
diff --git a/addressbook/libedata-book/e-data-book-factory.c b/addressbook/libedata-book/e-data-book-factory.c
index 4c1ce58..c420163 100644
--- a/addressbook/libedata-book/e-data-book-factory.c
+++ b/addressbook/libedata-book/e-data-book-factory.c
@@ -368,11 +368,14 @@ name_owner_changed (DBusGProxy *proxy,
 		gchar *key;
 		GList *list = NULL;
 		g_mutex_lock (factory->priv->connections_lock);
-		if (g_hash_table_lookup_extended (factory->priv->connections, prev_owner, (gpointer)&key, (gpointer)&list)) {
-			g_list_foreach (list, (GFunc)g_object_unref, NULL);
-			g_list_free (list);
-			g_hash_table_remove (factory->priv->connections, prev_owner);
+		while (g_hash_table_lookup_extended (factory->priv->connections, prev_owner, (gpointer)&key, (gpointer)&list)) {
+			/* this should trigger the book's weak ref notify
+			 * function, which will remove it from the list before
+			 * it's freed, and will remove the connection from
+			 * priv->connections once they're all gone */
+			g_object_unref (list->data);
 		}
+
 		g_mutex_unlock (factory->priv->connections_lock);
 	}
 }
diff --git a/calendar/libedata-cal/e-data-cal-factory.c b/calendar/libedata-cal/e-data-cal-factory.c
index 814942d..7bedc9a 100644
--- a/calendar/libedata-cal/e-data-cal-factory.c
+++ b/calendar/libedata-cal/e-data-cal-factory.c
@@ -452,11 +452,13 @@ name_owner_changed (DBusGProxy      *proxy,
 	if (strcmp (new_owner, "") == 0 && strcmp (name, prev_owner) == 0) {
 		gchar *key;
 		GList *list = NULL;
-		if (g_hash_table_lookup_extended (factory->priv->connections, prev_owner, (gpointer)&key, (gpointer)&list)) {
-			g_list_foreach (list, (GFunc)g_object_unref, NULL);
-			g_list_free (list);
-			g_hash_table_remove (factory->priv->connections, prev_owner);
-		}
+                while (g_hash_table_lookup_extended (factory->priv->connections, prev_owner, (gpointer)&key, (gpointer)&list)) {
+                        /* this should trigger the book's weak ref notify
+                         * function, which will remove it from the list before
+                         * it's freed, and will remove the connection from
+                         * priv->connections once they're all gone */
+                        g_object_unref (list->data);
+                }
 	}
 }
 



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