[gnome-bluetooth] Fix crash when first killswitch is added after startup



commit 12fee6fb240c32c0d277e6b8c5721afd4b89eb25
Author: Bryan Donlan <bdonlan gmail com>
Date:   Mon Oct 12 13:59:32 2009 -0400

    Fix crash when first killswitch is added after startup
    
    If the applet starts with no killswitches installed, the following code
    in main.c destroys the killswitch object:
    
    if (bluetooth_killswitch_has_killswitches (killswitch) == FALSE)
    {
    	g_object_unref (killswitch);
    	killswitch = NULL;
    }
    
    However, the destructor for the killswitch object
    (bluetooth_killswitch_finalize) fails to cleanup the io_watch set in its
    constructor. So when a killswitch is connected later, the event_cb for
    the killswitch object runs, and attempts to use the now-destructed
    killswitch object. The result is a crash.
    
    Moreover, just because we don't have a killswitch at startup doesn't
    mean we won't have one later.
    
    This patch corrects both issues, by fixing the finalizer, and removing
    the conditional destruction of the killswitch in main.c.
    
    Signed-off-by: Bryan Donlan <bdonlan gmail com>
    
    https://bugzilla.gnome.org/show_bug.cgi?id=598181

 applet/main.c              |    9 ++-------
 lib/bluetooth-killswitch.c |   15 +++++++++++----
 2 files changed, 13 insertions(+), 11 deletions(-)
---
diff --git a/applet/main.c b/applet/main.c
index 2112a9e..2f743f3 100644
--- a/applet/main.c
+++ b/applet/main.c
@@ -986,13 +986,8 @@ int main(int argc, char *argv[])
 	gtk_window_set_default_icon_name("bluetooth");
 
 	killswitch = bluetooth_killswitch_new ();
-	if (bluetooth_killswitch_has_killswitches (killswitch) == FALSE) {
-		g_object_unref (killswitch);
-		killswitch = NULL;
-	} else {
-		g_signal_connect (G_OBJECT (killswitch), "state-changed",
-				  G_CALLBACK (killswitch_state_changed), NULL);
-	}
+	g_signal_connect (G_OBJECT (killswitch), "state-changed",
+			  G_CALLBACK (killswitch_state_changed), NULL);
 
 	menu = create_popupmenu();
 
diff --git a/lib/bluetooth-killswitch.c b/lib/bluetooth-killswitch.c
index 3985029..05d6688 100644
--- a/lib/bluetooth-killswitch.c
+++ b/lib/bluetooth-killswitch.c
@@ -62,6 +62,7 @@ struct _BluetoothIndKillswitch {
 struct _BluetoothKillswitchPrivate {
 	int fd;
 	GIOChannel *channel;
+	guint watch_id;
 	GList *killswitches; /* a GList of BluetoothIndKillswitch */
 	BluetoothKillswitchPrivate *priv;
 };
@@ -308,10 +309,10 @@ bluetooth_killswitch_init (BluetoothKillswitch *killswitch)
 	/* Setup monitoring */
 	priv->fd = fd;
 	priv->channel = g_io_channel_unix_new (priv->fd);
-	g_io_add_watch (priv->channel,
-			G_IO_IN | G_IO_HUP | G_IO_ERR,
-			(GIOFunc) event_cb,
-			killswitch);
+	priv->watch_id = g_io_add_watch (priv->channel,
+				G_IO_IN | G_IO_HUP | G_IO_ERR,
+				(GIOFunc) event_cb,
+				killswitch);
 
 	g_signal_emit (G_OBJECT (killswitch),
 		       signals[STATE_CHANGED],
@@ -323,6 +324,12 @@ bluetooth_killswitch_finalize (GObject *object)
 {
 	BluetoothKillswitchPrivate *priv = BLUETOOTH_KILLSWITCH_GET_PRIVATE (object);
 
+	/* cleanup monitoring */
+	g_source_remove(priv->watch_id);
+	g_io_channel_shutdown(priv->channel, FALSE, NULL);
+	g_io_channel_unref(priv->channel);
+	close(priv->fd);
+
 	g_list_foreach (priv->killswitches, (GFunc) g_free, NULL);
 	g_list_free (priv->killswitches);
 	priv->killswitches = NULL;



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