From 653b7e4805a3c0204a9df0f7dbe26bc9cc03f094 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 18 Nov 2014 15:55:55 +0100 Subject: [PATCH] cli: Watch for device as well as AC state changes when activating The signals might be delivered in no particular order and we need to wait for the device to reach stable state (whether it's successfully conntected or not) as well as the active connection to leave ACTIVATING state. https://bugzilla.gnome.org/show_bug.cgi?id=740320 --- clients/cli/devices.c | 46 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/clients/cli/devices.c b/clients/cli/devices.c index 3499834d38..2b153362eb 100644 --- a/clients/cli/devices.c +++ b/clients/cli/devices.c @@ -1331,10 +1331,27 @@ progress_cb (gpointer user_data) return TRUE; } +static void connected_state_cb (NMDevice *device, NMActiveConnection *active); + static void -connected_state_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) +device_state_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) { NMActiveConnection *active = (NMActiveConnection *) user_data; + + connected_state_cb (device, active); +} + +static void +active_state_cb (NMActiveConnection *active, GParamSpec *pspec, gpointer user_data) +{ + NMDevice *device = (NMDevice *) user_data; + + connected_state_cb (device, active); +} + +static void +connected_state_cb (NMDevice *device, NMActiveConnection *active) +{ NMDeviceState state; NMDeviceStateReason reason; NMActiveConnectionState ac_state; @@ -1350,16 +1367,21 @@ connected_state_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) g_print (_("Device '%s' successfully activated with '%s'.\n"), nm_device_get_iface (device), nm_active_connection_get_uuid (active)); - g_object_unref (active); - quit (); } else if ( state <= NM_DEVICE_STATE_DISCONNECTED || state >= NM_DEVICE_STATE_DEACTIVATING) { reason = nm_device_get_state_reason (device); g_print (_("Error: Connection activation failed: (%d) %s.\n"), reason, nmc_device_reason_to_string (reason)); - g_object_unref (active); - quit (); - } + } else + return; + + g_signal_handlers_disconnect_by_func (active, G_CALLBACK (active_state_cb), device); + g_signal_handlers_disconnect_by_func (device, G_CALLBACK (device_state_cb), active); + + g_object_unref (active); + g_object_unref (device); + + quit (); } typedef struct { @@ -1393,6 +1415,7 @@ add_and_activate_cb (GObject *client, if (state == NM_ACTIVE_CONNECTION_STATE_UNKNOWN) { g_string_printf (nmc->return_text, _("Error: Failed to add/activate new connection: Unknown error")); nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; + g_object_unref (active); quit (); } @@ -1407,7 +1430,10 @@ add_and_activate_cb (GObject *client, g_object_unref (active); quit (); } else { - g_signal_connect (device, "notify::state", G_CALLBACK (connected_state_cb), active); + g_object_ref (device); + g_signal_connect (device, "notify::state", G_CALLBACK (device_state_cb), active); + g_signal_connect (active, "notify::state", G_CALLBACK (active_state_cb), device); + g_timeout_add_seconds (nmc->timeout, timeout_cb, nmc); /* Exit if timeout expires */ if (nmc->print_output == NMC_PRINT_PRETTY) @@ -1473,6 +1499,7 @@ connect_device_cb (GObject *client, GAsyncResult *result, gpointer user_data) if (devices->len == 0) { g_string_printf (nmc->return_text, _("Error: Device activation failed: device was disconnected")); nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; + g_object_unref (active); quit (); g_free (info); return; @@ -1487,9 +1514,12 @@ connect_device_cb (GObject *client, GAsyncResult *result, gpointer user_data) nmc_terminal_erase_line (); g_print (_("Device '%s' has been connected.\n"), nm_device_get_iface (device)); } + g_object_unref (active); quit (); } else { - g_signal_connect (device, "notify::state", G_CALLBACK (connected_state_cb), active); + g_object_ref (device); + g_signal_connect (device, "notify::state", G_CALLBACK (device_state_cb), active); + g_signal_connect (active, "notify::state", G_CALLBACK (active_state_cb), device); /* Start timer not to loop forever if "notify::state" signal is not issued */ g_timeout_add_seconds (nmc->timeout, timeout_cb, nmc); }