[network-manager-applet] editor: fix issues with multiple concurrent operations (rh #585405)



commit 64ff90de5a989fcd7dc1c1b00fe8bc7bf4182f66
Author: Dan Williams <dcbw redhat com>
Date:   Sun Apr 25 22:59:26 2010 -0700

    editor: fix issues with multiple concurrent operations (rh #585405)
    
    The editor was allowing itself to be closed while it was awaiting
    authorization for updates.  That's bad since (as yet) we don't
    have a way to cancel an ongoing operation that's blocked for
    authorization; that would require API changes to libnm-glib. So
    instead, just don't allow interaction with the editor until the
    user has completed or canceled authorization.
    
    Also fixes a small bug where the connection's scope would not be
    reset if the user canceled authorization.

 src/connection-editor/nm-connection-editor.c |   21 ++++++++++++-
 src/connection-editor/nm-connection-editor.h |    9 +++--
 src/connection-editor/nm-connection-list.c   |   43 +++++++++++++++++++++++++-
 3 files changed, 68 insertions(+), 5 deletions(-)
---
diff --git a/src/connection-editor/nm-connection-editor.c b/src/connection-editor/nm-connection-editor.c
index 8ab4280..47568d7 100644
--- a/src/connection-editor/nm-connection-editor.c
+++ b/src/connection-editor/nm-connection-editor.c
@@ -19,7 +19,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * (C) Copyright 2007 - 2008 Red Hat, Inc.
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
  * (C) Copyright 2007 - 2008 Novell, Inc.
  */
 
@@ -851,3 +851,22 @@ nm_connection_editor_get_window (NMConnectionEditor *editor)
 	return GTK_WINDOW (editor->window);
 }
 
+gboolean
+nm_connection_editor_get_busy (NMConnectionEditor *editor)
+{
+	g_return_val_if_fail (NM_IS_CONNECTION_EDITOR (editor), FALSE);
+
+	return editor->busy;
+}
+
+void
+nm_connection_editor_set_busy (NMConnectionEditor *editor, gboolean busy)
+{
+	g_return_if_fail (NM_IS_CONNECTION_EDITOR (editor));
+
+	if (busy != editor->busy) {
+		editor->busy = busy;
+		gtk_widget_set_sensitive (editor->window, !busy);
+	}
+}
+
diff --git a/src/connection-editor/nm-connection-editor.h b/src/connection-editor/nm-connection-editor.h
index 63e1c63..4fe21e6 100644
--- a/src/connection-editor/nm-connection-editor.h
+++ b/src/connection-editor/nm-connection-editor.h
@@ -1,8 +1,6 @@
 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 /* NetworkManager Connection editor -- Connection editor for NetworkManager
  *
- * Rodrigo Moya <rodrigo gnome-db org>
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -17,7 +15,8 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * (C) Copyright 2004-2005 Red Hat, Inc.
+ * (C) Copyright 2007 Rodrigo Moya <rodrigo gnome-db org>
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
  */
 
 #ifndef NM_CONNECTION_EDITOR_H
@@ -58,6 +57,8 @@ typedef struct {
 	GtkWidget *window;
 	GtkWidget *ok_button;
 	GtkWidget *cancel_button;
+
+	gboolean busy;
 } NMConnectionEditor;
 
 typedef struct {
@@ -78,5 +79,7 @@ void                nm_connection_editor_save_vpn_secrets (NMConnectionEditor *e
 NMConnection *      nm_connection_editor_get_connection (NMConnectionEditor *editor);
 gboolean            nm_connection_editor_update_connection (NMConnectionEditor *editor, GError **error);
 GtkWindow *         nm_connection_editor_get_window (NMConnectionEditor *editor);
+gboolean            nm_connection_editor_get_busy (NMConnectionEditor *editor);
+void                nm_connection_editor_set_busy (NMConnectionEditor *editor, gboolean busy);
 
 #endif
diff --git a/src/connection-editor/nm-connection-list.c b/src/connection-editor/nm-connection-list.c
index 0500442..a6b20b5 100644
--- a/src/connection-editor/nm-connection-list.c
+++ b/src/connection-editor/nm-connection-list.c
@@ -18,7 +18,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * (C) Copyright 2007 - 2009 Red Hat, Inc.
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
  */
 
 #include <config.h>
@@ -312,6 +312,7 @@ typedef void (*DeleteResultFunc) (NMConnectionList *list,
 typedef struct {
 	NMConnectionList *list;
 	NMSettingsConnectionInterface *original;
+	NMConnectionEditor *editor;
 	DeleteResultFunc callback;
 	gpointer callback_data;
 } DeleteInfo;
@@ -325,6 +326,9 @@ delete_cb (NMSettingsConnectionInterface *connection_iface,
 	NMConnection *connection = NM_CONNECTION (connection_iface);
 	NMConnectionScope scope;
 
+	if (info->editor)
+		nm_connection_editor_set_busy (info->editor, FALSE);
+
 	scope = nm_connection_get_scope (connection);
 	if (!error && (scope == NM_CONNECTION_SCOPE_USER)) {
 		NMSettingConnection *s_con;
@@ -368,11 +372,18 @@ delete_connection (NMConnectionList *list,
                    gpointer user_data)
 {
 	DeleteInfo *info;
+	NMConnectionEditor *editor;
+
+	editor = g_hash_table_lookup (list->editors, connection);
 
 	info = g_malloc0 (sizeof (DeleteInfo));
 	info->list = list;
 	info->callback = callback;
 	info->callback_data = user_data;
+	info->editor = editor;
+
+	if (editor)
+		nm_connection_editor_set_busy (editor, TRUE);
 
 	nm_settings_connection_interface_delete (connection, delete_cb, info);
 }
@@ -399,6 +410,8 @@ add_cb (NMSettingsInterface *settings,
 	AddInfo *info = user_data;
 	NMConnection *connection;
 
+	nm_connection_editor_set_busy (info->editor, FALSE);
+
 	if (!error) {
 		/* Let the VPN plugin save its secrets */
 		connection = nm_connection_editor_get_connection (info->editor);
@@ -437,6 +450,7 @@ add_connection (NMConnectionList *self,
 	else
 		g_assert_not_reached ();
 
+	nm_connection_editor_set_busy (editor, TRUE);
 	nm_settings_interface_add_connection (settings, connection, add_cb, info);
 }
 
@@ -452,6 +466,7 @@ typedef struct {
 	NMConnectionList *list;
 	NMConnectionEditor *editor;
 	NMSettingsConnectionInterface *connection;
+	NMConnectionScope orig_scope;
 	UpdateResultFunc callback;
 	gpointer callback_data;
 } UpdateInfo;
@@ -480,6 +495,8 @@ update_add_result_cb (NMConnectionList *list, GError *error, gpointer user_data)
 	UpdateInfo *info = user_data;
 
 	if (error) {
+		/* set the old scope back on the connection */
+		nm_connection_set_scope (NM_CONNECTION (info->connection), info->orig_scope);
 		update_complete (info, error);
 		return;
 	}
@@ -495,6 +512,8 @@ update_cb (NMSettingsConnectionInterface *connection,
 {
 	UpdateInfo *info = user_data;
 
+	nm_connection_editor_set_busy (info->editor, FALSE);
+
 	if (!error) {
 		/* Save user-connection vpn secrets */
 		if (nm_connection_get_scope (NM_CONNECTION (connection)) == NM_CONNECTION_SCOPE_USER)
@@ -524,6 +543,7 @@ update_connection (NMConnectionList *list,
 	info->list = list;
 	info->editor = editor;
 	info->connection = g_object_ref (connection);
+	info->orig_scope = orig_scope;
 	info->callback = callback;
 	info->callback_data = user_data;
 
@@ -551,6 +571,7 @@ update_connection (NMConnectionList *list,
 		/* Update() actually saves the connection settings to backing storage,
 		 * either GConf or over D-Bus.
 		 */
+		nm_connection_editor_set_busy (editor, TRUE);
 		nm_settings_connection_interface_update (connection, update_cb, info);
 	} else {
 		/* The hard part: Connection scope changed:
@@ -585,6 +606,12 @@ add_response_cb (NMConnectionEditor *editor, gint response, GError *error, gpoin
 	ActionInfo *info = (ActionInfo *) user_data;
 	GError *add_error = NULL;
 
+	/* if the dialog is busy waiting for authorization or something,
+	 * don't destroy it until authorization returns.
+	 */
+	if (nm_connection_editor_get_busy (editor))
+		return;
+
 	if (response == GTK_RESPONSE_OK) {
 		/* Verify and commit user changes */
 		if (nm_connection_editor_update_connection (editor, &add_error)) {
@@ -721,6 +748,12 @@ edit_done_cb (NMConnectionEditor *editor, gint response, GError *error, gpointer
 	NMConnection *connection;
 	GError *edit_error = NULL;
 
+	/* if the dialog is busy waiting for authorization or something,
+	 * don't destroy it until authorization returns.
+	 */
+	if (nm_connection_editor_get_busy (editor))
+		return;
+
 	connection = nm_connection_editor_get_connection (editor);
 	g_assert (connection);
 
@@ -817,6 +850,7 @@ delete_clicked (GtkButton *button, gpointer user_data)
 {
 	ActionInfo *info = (ActionInfo *) user_data;
 	NMSettingsConnectionInterface *connection;
+	NMConnectionEditor *editor;
 	NMSettingConnection *s_con;
 	GtkWidget *dialog;
 	const char *id;
@@ -825,6 +859,13 @@ delete_clicked (GtkButton *button, gpointer user_data)
 	connection = get_active_connection (info->treeview);
 	g_return_if_fail (connection != NULL);
 
+	editor = g_hash_table_lookup (info->list->editors, connection);
+	if (editor && nm_connection_editor_get_busy (editor)) {
+		/* Editor already has an operation in progress, raise it */
+		nm_connection_editor_present (editor);
+		return;
+	}
+
 	s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION);
 	g_assert (s_con);
 	id = nm_setting_connection_get_id (s_con);



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