Blob Blame History Raw
From 5d3457e46dcca007296f5dd7f78f59272c0072d3 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Fri, 20 Sep 2013 19:04:07 +0200
Subject: [PATCH] bluetooth: Fix crash when exiting during a connection

If a connection is on-going, make sure to cancel it before
when finalizing the panel, or we will be crashing once
we've finished connecting/disconnecting.

https://bugzilla.gnome.org/show_bug.cgi?id=708478
---
 panels/bluetooth/cc-bluetooth-panel.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/panels/bluetooth/cc-bluetooth-panel.c b/panels/bluetooth/cc-bluetooth-panel.c
index 9784044..cfabae8 100644
--- a/panels/bluetooth/cc-bluetooth-panel.c
+++ b/panels/bluetooth/cc-bluetooth-panel.c
@@ -57,6 +57,7 @@ struct CcBluetoothPanelPrivate {
 	gboolean             debug;
 	GHashTable          *connecting_devices;
 	GtkWidget           *kill_switch_header;
+	GCancellable        *cancellable;
 };
 
 static void cc_bluetooth_panel_finalize (GObject *object);
@@ -101,6 +102,9 @@ cc_bluetooth_panel_finalize (GObject *object)
 	bluetooth_plugin_manager_cleanup ();
 
 	self = CC_BLUETOOTH_PANEL (object);
+	g_cancellable_cancel (self->priv->cancellable);
+	g_clear_object (&self->priv->cancellable);
+
 	g_clear_object (&self->priv->builder);
 	g_clear_object (&self->priv->killswitch);
 	g_clear_object (&self->priv->client);
@@ -165,10 +169,13 @@ connect_done (GObject      *source_object,
 	CcBluetoothPanel *self;
 	char *bdaddr;
 	gboolean success;
+	GError *error = NULL;
 	ConnectData *data = (ConnectData *) user_data;
 
 	success = bluetooth_client_connect_service_finish (BLUETOOTH_CLIENT (source_object),
-							   res, NULL);
+							   res, &error);
+	if (!success && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+		goto out;
 
 	self = data->self;
 
@@ -187,7 +194,9 @@ connect_done (GObject      *source_object,
 	remove_connecting (self, data->bdaddr);
 
 	g_free (bdaddr);
-	g_object_unref (data->self);
+
+out:
+	g_clear_error (&error);
 	g_free (data->bdaddr);
 	g_free (data);
 }
@@ -221,12 +230,12 @@ switch_connected_active_changed (GtkSwitch        *button,
 
 	data = g_new0 (ConnectData, 1);
 	data->bdaddr = bdaddr;
-	data->self = g_object_ref (self);
+	data->self = self;
 
 	bluetooth_client_connect_service (self->priv->client,
 					  proxy,
 					  gtk_switch_get_active (button),
-					  NULL,
+					  self->priv->cancellable,
 					  connect_done,
 					  data);
 
@@ -786,6 +795,7 @@ cc_bluetooth_panel_init (CcBluetoothPanel *self)
 	g_resources_register (cc_bluetooth_get_resource ());
 
 	bluetooth_plugin_manager_init ();
+	self->priv->cancellable = g_cancellable_new ();
 	self->priv->killswitch = bluetooth_killswitch_new ();
 	self->priv->client = bluetooth_client_new ();
 	self->priv->connecting_devices = g_hash_table_new_full (g_str_hash,
-- 
1.8.4.2