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

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