diff -pur dbus/glib/dbus-gproxy.c dbus.new/glib/dbus-gproxy.c --- dbus/glib/dbus-gproxy.c 2006-09-18 14:54:25.000000000 +0300 +++ dbus.new/glib/dbus-gproxy.c 2006-10-12 13:42:00.530001528 +0300 @@ -713,18 +713,21 @@ dbus_g_proxy_manager_replace_name_owner names = g_hash_table_lookup (manager->owner_names, prev_owner); - link = g_slist_find_custom (names, name, find_name_in_info); - info = NULL; - if (link != NULL) - { - info = link->data; + if (names != NULL) + { + link = g_slist_find_custom (names, name, find_name_in_info); + + if (link != NULL) + { + info = link->data; - names = g_slist_delete_link (names, link); + names = g_slist_delete_link (names, link); - if (names == NULL) - g_hash_table_remove (manager->owner_names, prev_owner); - } + if (names == NULL) + g_hash_table_remove (manager->owner_names, prev_owner); + } + } if (new_owner[0] == '\0') { @@ -740,13 +743,29 @@ dbus_g_proxy_manager_replace_name_owner UNLOCK_MANAGER (manager); + /* ref all proxies before destroying them, because + * destroying one proxy may cause client code to + * unref other proxies further down our list, meaning + * that we end up calling the destroy method on + * objects which have already been finalised. using + * weak references would be a neater way to fix this. */ + for (tmp = data.destroyed; tmp; tmp = tmp->next) + g_object_ref (tmp->data); for (tmp = data.destroyed; tmp; tmp = tmp->next) dbus_g_proxy_destroy (tmp->data); + for (tmp = data.destroyed; tmp; tmp = tmp->next) + g_object_unref (tmp->data); g_slist_free (data.destroyed); LOCK_MANAGER (manager); + + if (info) + { + g_free (info->name); + g_free (info); + } } - else + else if (info) { insert_nameinfo (manager, new_owner, info); }