[network-manager-netbook] Rework a bit to make it not crash



commit 7145787e03f3050818caa22657ee181ad5168e6e
Author: Tambet Ingo <tambet gmail com>
Date:   Thu Dec 10 11:29:35 2009 +0200

    Rework a bit to make it not crash
    
    Turns out it was a bad idea to create/dispose settings each time they're
    needed - deletion is asyncronous and need the settings to be present when
    it's done.

 gnome-bluetooth/network-manager-applet.c |  123 ++++++++++++------------------
 1 files changed, 49 insertions(+), 74 deletions(-)
---
diff --git a/gnome-bluetooth/network-manager-applet.c b/gnome-bluetooth/network-manager-applet.c
index e9a8117..946b287 100644
--- a/gnome-bluetooth/network-manager-applet.c
+++ b/gnome-bluetooth/network-manager-applet.c
@@ -70,22 +70,11 @@ get_array_from_bdaddr (const char *str)
 }
 
 typedef struct {
-	GSList *settings;
 	GMainLoop *loop;
 	guint counter;
 } GetSettingsSyncInfo;
 
 static void
-connection_added (NMSettingsInterface *settings,
-				  NMSettingsConnectionInterface *connection,
-				  gpointer user_data)
-{
-	GetSettingsSyncInfo *info = user_data;
-
-	info->settings = g_slist_prepend (info->settings, g_object_ref (connection));
-}
-
-static void
 connections_read (NMSettingsInterface *settings,
 				  gpointer user_data)
 {
@@ -107,12 +96,13 @@ get_settings_timed_out (gpointer user_data)
 	return FALSE;
 }
 
-static GSList *
-get_settings_sync ()
+static NMSettingsInterface *user_settings = NULL;
+static NMSettingsInterface *system_settings = NULL;
+
+static gboolean
+init_settings ()
 {
 	DBusGConnection *bus;
-	NMSettingsInterface *user_settings;
-	NMSettingsInterface *system_settings;
 	GetSettingsSyncInfo info;
 	GError *err = NULL;
 	gboolean running;
@@ -121,17 +111,15 @@ get_settings_sync ()
 	if (!bus) {
 		g_warning ("Couldn't connect to system bus: %s", err->message);
 		g_error_free (err);
-		return NULL;
+		return FALSE;
 	}
 
-	info.settings = NULL;
 	info.loop = g_main_loop_new (NULL, FALSE);
 	info.counter = 0;
 
 	user_settings = NM_SETTINGS_INTERFACE (nm_remote_settings_new (bus, NM_CONNECTION_SCOPE_USER));
 	g_object_get (user_settings, NM_REMOTE_SETTINGS_SERVICE_RUNNING, &running, NULL);
 	if (running) {
-		g_signal_connect (user_settings, "new-connection", G_CALLBACK (connection_added), &info);
 		g_signal_connect (user_settings, "connections-read", G_CALLBACK (connections_read), &info);
 		info.counter++;
 	}
@@ -139,7 +127,6 @@ get_settings_sync ()
 	system_settings = NM_SETTINGS_INTERFACE (nm_remote_settings_system_new (bus));
 	g_object_get (system_settings, NM_REMOTE_SETTINGS_SERVICE_RUNNING, &running, NULL);
 	if (running) {
-		g_signal_connect (system_settings, "new-connection", G_CALLBACK (connection_added), &info);
 		g_signal_connect (system_settings, "connections-read", G_CALLBACK (connections_read), &info);
 		info.counter++;
 	}
@@ -147,17 +134,32 @@ get_settings_sync ()
 	dbus_g_connection_unref (bus);
 
 	if (info.counter > 0) {
+		guint timeout_id;
+
 		/* Add a timer so that we don't wait here forever in case we never
 		   get signaled that services are read */
-		g_timeout_add_seconds (5, get_settings_timed_out, &info);
+		timeout_id = g_timeout_add_seconds (5, get_settings_timed_out, &info);
 		g_main_loop_run (info.loop);
+		g_source_remove (timeout_id);
 	}
 
 	g_main_loop_unref (info.loop);
-	g_object_unref (user_settings);
-	g_object_unref (system_settings);
 
-	return info.settings;
+	return TRUE;
+}
+
+static GSList *
+get_settings (void)
+{
+	GSList *list;
+
+	if (!user_settings && !system_settings && !init_settings ())
+		return NULL;
+
+	list = nm_settings_interface_list_connections (user_settings);
+	list = g_slist_concat (list, nm_settings_interface_list_connections (system_settings));
+
+	return list;
 }
 
 static NMSettingsConnectionInterface *
@@ -171,7 +173,7 @@ get_connection_for_bdaddr (const char *bdaddr)
 	if (array == NULL)
 		return NULL;
 
-	list = get_settings_sync ();
+	list = get_settings ();
 	for (l = list; l != NULL; l = l->next) {
 		NMSettingsConnectionInterface *candidate = l->data;
 		NMSetting *setting;
@@ -187,17 +189,17 @@ get_connection_for_bdaddr (const char *bdaddr)
 		addr = nm_setting_bluetooth_get_bdaddr (NM_SETTING_BLUETOOTH (setting));
 		if (addr == NULL || memcmp (addr->data, array->data, addr->len) != 0)
 			continue;
-		found = g_object_ref (candidate);
+		found = candidate;
 		break;
 	}
 
-	g_slist_foreach (list, (GFunc) g_object_unref, NULL);
+	g_byte_array_free (array, TRUE);
 	g_slist_free (list);
 
 	return found;
 }
 
-static NMConnection *
+static void
 create_connection (const char *bdaddr)
 {
 	NMConnection *connection;
@@ -207,7 +209,7 @@ create_connection (const char *bdaddr)
 
 	mac = get_array_from_bdaddr (bdaddr);
 	if (mac == NULL)
-		return NULL;
+		return;
 
 	/* The connection */
 	connection = nm_connection_new ();
@@ -243,8 +245,7 @@ create_connection (const char *bdaddr)
 	nm_connection_add_setting (connection, setting);
 
 	nm_gconf_write_connection (connection, NULL, NULL);
-
-	return connection;
+	g_object_unref (connection);
 }
 
 static void
@@ -254,47 +255,32 @@ delete_cb (NMSettingsConnectionInterface *connection,
 {
 	if (error)
 		g_warning ("Error deleting connection: (%d) %s", error->code, error->message);
-	if (user_data)
-		g_object_set_data (G_OBJECT (user_data), "conn", NULL);
 }
 
 static void
-delete_connection (GObject *button, NMConnection *connection)
+delete_connection (const char *bdaddr)
 {
-	NMSettingsConnectionInterface *ci;
-
-	if (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection))
-		ci = NM_SETTINGS_CONNECTION_INTERFACE (connection);
-	else {
-		const char *bdaddr;
-
-		bdaddr = g_object_get_data (button, "bdaddr");
-		g_assert (bdaddr);
-		ci = get_connection_for_bdaddr (bdaddr);
-	}
+	NMSettingsConnectionInterface *connection;
 
-	if (ci)
-		nm_settings_connection_interface_delete (ci, delete_cb, button);
+	// FIXME: don't just delete any random PAN conenction for this
+	// bdaddr, actually delete the one this plugin created
+	connection = get_connection_for_bdaddr (bdaddr);
+	if (connection)
+		nm_settings_connection_interface_delete (connection, delete_cb, NULL);
 }
 
 static void
 button_toggled (GtkToggleButton *button, gpointer user_data)
 {
-	NMConnection *connection;
-
-	if (gtk_toggle_button_get_active (button) == FALSE) {
-		connection = g_object_get_data (G_OBJECT (button), "conn");
-		delete_connection (G_OBJECT (button), connection);
-	} else {
-		const char *bdaddr;
+	const char *bdaddr;
 
-		bdaddr = g_object_get_data (G_OBJECT (button), "bdaddr");
-		g_assert (bdaddr);
+	bdaddr = g_object_get_data (G_OBJECT (button), "bdaddr");
+	g_assert (bdaddr);
 
-		connection = create_connection (bdaddr);
-		if (connection)
-			g_object_set_data_full (G_OBJECT (button), "conn", connection, g_object_unref);
-	}
+	if (gtk_toggle_button_get_active (button) == FALSE)
+		delete_connection (bdaddr);
+	else
+		create_connection (bdaddr);
 }
 
 static GtkWidget *
@@ -307,12 +293,10 @@ get_config_widgets (const char *bdaddr, const char **uuids)
 	g_object_set_data_full (G_OBJECT (button),
 	                        "bdaddr", g_strdup (bdaddr),
 	                        (GDestroyNotify) g_free);
+
 	connection = get_connection_for_bdaddr (bdaddr);
-	if (connection != NULL) {
-		g_object_set_data_full (G_OBJECT (button), "conn", connection, g_object_unref);
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-	}
-	g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK (button_toggled), NULL);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), connection != NULL);
+	g_signal_connect (button, "toggled", G_CALLBACK (button_toggled), NULL);
 
 	return button;
 }
@@ -320,17 +304,8 @@ get_config_widgets (const char *bdaddr, const char **uuids)
 static void
 device_removed (const char *bdaddr)
 {
-	NMSettingsConnectionInterface *connection;
-
 	g_message ("Device '%s' got removed", bdaddr);
-
-	// FIXME: don't just delete any random PAN conenction for this
-	// bdaddr, actually delete the one this plugin created
-	connection = get_connection_for_bdaddr (bdaddr);
-	if (connection) {
-		nm_settings_connection_interface_delete (connection, delete_cb, NULL);
-		g_object_unref (connection);
-	}
+	delete_connection (bdaddr);
 }
 
 static GbtPluginInfo plugin_info = {



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