Blame SOURCES/0001-UPnP-Disconnect-signal-handlers-during-destruction.patch

90f887
From 916daa1bf04bfb1d8823c3f677a021bf41df1db0 Mon Sep 17 00:00:00 2001
90f887
From: Debarshi Ray <debarshir@freedesktop.org>
90f887
Date: Tue, 20 Jan 2015 13:59:33 +0100
90f887
Subject: [PATCH] Disconnect signal handlers during destruction
90f887
90f887
A GUPnPContextManager can outlive a dlr_upnp_t because it might be
90f887
using asynchronous operations during its construction (eg.,
90f887
GUPnPNetworkManager) which retain references to it. This can be
90f887
demonstrated if the service is spawned as a result of the following
90f887
command:
90f887
$ gdbus call \
90f887
    --session \
90f887
    --dest com.intel.dleyna-renderer \
90f887
    --object-path /com/intel/dLeynaRenderer \
90f887
    --method com.intel.dLeynaRenderer.Manager.Release
90f887
90f887
This leads to the signal handlers being invoked with an invalid
90f887
dlr_upnp_t and the outcome is a crash.
90f887
90f887
To avoid this, we should disconnect the callbacks listening to the
90f887
context manager and the control points belonging to it.
90f887
---
90f887
 libdleyna/renderer/upnp.c | 20 ++++++++++++++++++++
90f887
 1 file changed, 20 insertions(+)
90f887
90f887
diff --git a/libdleyna/renderer/upnp.c b/libdleyna/renderer/upnp.c
90f887
index 17cbda720bc1..707dc09aaf5a 100644
90f887
--- a/libdleyna/renderer/upnp.c
90f887
+++ b/libdleyna/renderer/upnp.c
90f887
@@ -45,6 +45,7 @@ struct dlr_upnp_t_ {
90f887
 	void *user_data;
90f887
 	GHashTable *server_udn_map;
90f887
 	GHashTable *server_uc_map;
90f887
+	GList *cps;
90f887
 	dlr_host_service_t *host_service;
90f887
 };
90f887
 
90f887
@@ -352,6 +353,7 @@ static void prv_on_context_available(GUPnPContextManager *context_manager,
90f887
 
90f887
 	gssdp_resource_browser_set_active(GSSDP_RESOURCE_BROWSER(cp), TRUE);
90f887
 	gupnp_context_manager_manage_control_point(upnp->context_manager, cp);
90f887
+	upnp->cps = g_list_prepend (upnp->cps, g_object_ref (cp));
90f887
 	g_object_unref(cp);
90f887
 }
90f887
 
90f887
@@ -390,10 +392,28 @@ dlr_upnp_t *dlr_upnp_new(dleyna_connector_id_t connection,
90f887
 void dlr_upnp_delete(dlr_upnp_t *upnp)
90f887
 {
90f887
 	if (upnp) {
90f887
+		GList *l;
90f887
+
90f887
+		for (l = upnp->cps; l != NULL; l = l->next) {
90f887
+			GUPnPControlPoint *cp = GUPNP_CONTROL_POINT (l->data);
90f887
+
90f887
+			g_signal_handlers_disconnect_by_func (cp,
90f887
+							      prv_server_available_cb,
90f887
+							      upnp);
90f887
+			g_signal_handlers_disconnect_by_func (cp,
90f887
+							      prv_server_unavailable_cb,
90f887
+							      upnp);
90f887
+		}
90f887
+
90f887
+		g_signal_handlers_disconnect_by_func (upnp->context_manager,
90f887
+						      prv_on_context_available,
90f887
+						      upnp);
90f887
+
90f887
 		dlr_host_service_delete(upnp->host_service);
90f887
 		g_object_unref(upnp->context_manager);
90f887
 		g_hash_table_unref(upnp->server_udn_map);
90f887
 		g_hash_table_unref(upnp->server_uc_map);
90f887
+		g_list_free_full (upnp->cps, g_object_unref);
90f887
 
90f887
 		g_free(upnp);
90f887
 	}
90f887
-- 
90f887
2.9.5
90f887