diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2014-08-06 11:05:32 +0200 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2015-01-21 18:36:00 -0600 |
commit | ec61601a2234bc57fdd0aaeb090a0dd550521c58 (patch) | |
tree | c040d9929f83013b769492119413edf8575d64aa | |
parent | 14f732e8df6a5bfbc36d0e0adaec175d7da6f231 (diff) | |
download | NetworkManager-ec61601a2234bc57fdd0aaeb090a0dd550521c58.tar.gz |
wwan,modem: let disconnect() be an async operation
-rw-r--r-- | src/devices/wwan/nm-modem-broadband.c | 75 | ||||
-rw-r--r-- | src/devices/wwan/nm-modem.c | 2 | ||||
-rw-r--r-- | src/devices/wwan/nm-modem.h | 9 |
3 files changed, 67 insertions, 19 deletions
diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c index f8239b7990..fcab416ef6 100644 --- a/src/devices/wwan/nm-modem-broadband.c +++ b/src/devices/wwan/nm-modem-broadband.c @@ -844,20 +844,47 @@ stage3_ip6_config_request (NMModem *_self, NMDeviceStateReason *reason) typedef struct { NMModemBroadband *self; + GSimpleAsyncResult *result; + GCancellable *cancellable; gboolean warn; -} SimpleDisconnectContext; +} DisconnectContext; static void -simple_disconnect_context_free (SimpleDisconnectContext *ctx) +disconnect_context_complete (DisconnectContext *ctx) { + g_simple_async_result_complete_in_idle (ctx->result); + if (ctx->cancellable) + g_object_unref (ctx->cancellable); + g_object_unref (ctx->result); g_object_unref (ctx->self); - g_slice_free (SimpleDisconnectContext, ctx); + g_slice_free (DisconnectContext, ctx); +} + +static gboolean +disconnect_context_complete_if_cancelled (DisconnectContext *ctx) +{ + GError *error = NULL; + + if (g_cancellable_set_error_if_cancelled (ctx->cancellable, &error)) { + g_simple_async_result_take_error (ctx->result, error); + disconnect_context_complete (ctx); + return TRUE; + } + return FALSE; +} + +static gboolean +disconnect_finish (NMModem *self, + GAsyncResult *res, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); } static void simple_disconnect_ready (MMModemSimple *modem_iface, GAsyncResult *res, - SimpleDisconnectContext *ctx) + DisconnectContext *ctx) { GError *error = NULL; @@ -865,33 +892,46 @@ simple_disconnect_ready (MMModemSimple *modem_iface, if (ctx->warn) nm_log_warn (LOGD_MB, "(%s) failed to disconnect modem: %s", nm_modem_get_uid (NM_MODEM (ctx->self)), - error && error->message ? error->message : "(unknown)"); - g_clear_error (&error); + error->message); + g_simple_async_result_take_error (ctx->result, error); } - simple_disconnect_context_free (ctx); + disconnect_context_complete (ctx); } static void -disconnect (NMModem *modem, - gboolean warn) +disconnect (NMModem *self, + gboolean warn, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - NMModemBroadband *self = NM_MODEM_BROADBAND (modem); - SimpleDisconnectContext *ctx; - - if (!self->priv->simple_iface) - return; + DisconnectContext *ctx; - ctx = g_slice_new (SimpleDisconnectContext); + ctx = g_slice_new (DisconnectContext); ctx->self = g_object_ref (self); - + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + disconnect); /* Don't bother warning on FAILED since the modem is already gone */ ctx->warn = warn; + /* Setup cancellable */ + ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + if (disconnect_context_complete_if_cancelled (ctx)) + return; + + /* If no simple iface, we're done */ + if (!ctx->self->priv->simple_iface) { + disconnect_context_complete (ctx); + return; + } + mm_modem_simple_disconnect ( ctx->self->priv->simple_iface, NULL, /* bearer path; if NULL given ALL get disconnected */ - NULL, /* cancellable */ + cancellable, (GAsyncReadyCallback)simple_disconnect_ready, ctx); } @@ -1142,6 +1182,7 @@ nm_modem_broadband_class_init (NMModemBroadbandClass *klass) modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; modem_class->stage3_ip6_config_request = stage3_ip6_config_request; modem_class->disconnect = disconnect; + modem_class->disconnect_finish = disconnect_finish; modem_class->deactivate = deactivate; modem_class->set_mm_enabled = set_mm_enabled; modem_class->get_user_pass = get_user_pass; diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index ba1db8a4e0..04fc798ccc 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -924,7 +924,7 @@ nm_modem_device_state_changed (NMModem *self, /* Don't bother warning on FAILED since the modem is already gone */ if (new_state == NM_DEVICE_STATE_FAILED) warn = FALSE; - NM_MODEM_GET_CLASS (self)->disconnect (self, warn); + NM_MODEM_GET_CLASS (self)->disconnect (self, warn, NULL, NULL, NULL); } break; default: diff --git a/src/devices/wwan/nm-modem.h b/src/devices/wwan/nm-modem.h index 2a4d917332..a4c6702c52 100644 --- a/src/devices/wwan/nm-modem.h +++ b/src/devices/wwan/nm-modem.h @@ -143,7 +143,14 @@ typedef struct { void (*set_mm_enabled) (NMModem *self, gboolean enabled); - void (*disconnect) (NMModem *self, gboolean warn); + void (*disconnect) (NMModem *self, + gboolean warn, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*disconnect_finish) (NMModem *self, + GAsyncResult *res, + GError **error); void (*deactivate) (NMModem *self, NMDevice *device); |