diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2013-04-11 19:21:21 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2013-04-17 15:19:39 +0200 |
commit | 659d942c33767d44f2470aee183b0eb0fc268016 (patch) | |
tree | a227fb54afab8b94c948a1a205a6363ae73ca2f6 | |
parent | d1d5616ca5607836fc2a17024555ef2578bb6d8e (diff) |
mbim-port: make port closing async always
Don't just close the port and forget, really wait to get the CLOSE response
before going on.
-rw-r--r-- | src/mm-broadband-modem-mbim.c | 5 | ||||
-rw-r--r-- | src/mm-mbim-port.c | 117 | ||||
-rw-r--r-- | src/mm-mbim-port.h | 23 | ||||
-rw-r--r-- | src/mm-port-probe.c | 28 |
4 files changed, 118 insertions, 55 deletions
diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c index eabb29b9..0b236554 100644 --- a/src/mm-broadband-modem-mbim.c +++ b/src/mm-broadband-modem-mbim.c @@ -876,9 +876,8 @@ finalize (GObject *object) mbim = mm_base_modem_peek_port_mbim (MM_BASE_MODEM (self)); /* If we did open the MBIM port during initialization, close it now */ - if (mbim && - mm_mbim_port_is_open (mbim)) { - mm_mbim_port_close (mbim); + if (mbim && mm_mbim_port_is_open (mbim)) { + mm_mbim_port_close (mbim, NULL, NULL); } G_OBJECT_CLASS (mm_broadband_modem_mbim_parent_class)->finalize (object); diff --git a/src/mm-mbim-port.c b/src/mm-mbim-port.c index 0a5499d1..cc8a9700 100644 --- a/src/mm-mbim-port.c +++ b/src/mm-mbim-port.c @@ -25,7 +25,7 @@ G_DEFINE_TYPE (MMMbimPort, mm_mbim_port, MM_TYPE_PORT) struct _MMMbimPortPrivate { - gboolean opening; + gboolean in_progress; MbimDevice *mbim_device; }; @@ -35,19 +35,39 @@ typedef struct { MMMbimPort *self; GSimpleAsyncResult *result; GCancellable *cancellable; -} PortOpenContext; +} PortContext; static void -port_open_context_complete_and_free (PortOpenContext *ctx) +port_context_complete_and_free (PortContext *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 (PortOpenContext, ctx); + g_slice_free (PortContext, ctx); } +static PortContext * +port_context_new (MMMbimPort *self, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + PortContext *ctx; + + ctx = g_slice_new0 (PortContext); + ctx->self = g_object_ref (self); + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + port_context_new); + ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + return ctx; +} + +/*****************************************************************************/ + gboolean mm_mbim_port_open_finish (MMMbimPort *self, GAsyncResult *res, @@ -59,12 +79,12 @@ mm_mbim_port_open_finish (MMMbimPort *self, static void mbim_device_open_ready (MbimDevice *mbim_device, GAsyncResult *res, - PortOpenContext *ctx) + PortContext *ctx) { GError *error = NULL; - /* Reset the opening flag */ - ctx->self->priv->opening = FALSE; + /* Reset the progress flag */ + ctx->self->priv->in_progress = FALSE; if (!mbim_device_open_finish (mbim_device, res, &error)) { g_clear_object (&ctx->self->priv->mbim_device); @@ -72,20 +92,20 @@ mbim_device_open_ready (MbimDevice *mbim_device, } else g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); - port_open_context_complete_and_free (ctx); + port_context_complete_and_free (ctx); } static void mbim_device_new_ready (GObject *unused, GAsyncResult *res, - PortOpenContext *ctx) + PortContext *ctx) { GError *error = NULL; ctx->self->priv->mbim_device = mbim_device_new_finish (res, &error); if (!ctx->self->priv->mbim_device) { g_simple_async_result_take_error (ctx->result, error); - port_open_context_complete_and_free (ctx); + port_context_complete_and_free (ctx); return; } @@ -105,37 +125,31 @@ mm_mbim_port_open (MMMbimPort *self, { GFile *file; gchar *fullpath; - PortOpenContext *ctx; + PortContext *ctx; g_return_if_fail (MM_IS_MBIM_PORT (self)); - ctx = g_slice_new0 (PortOpenContext); - ctx->self = g_object_ref (self); - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - mm_mbim_port_open); - ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + ctx = port_context_new (self, cancellable, callback, user_data); - if (self->priv->opening) { + if (self->priv->in_progress) { g_simple_async_result_set_error (ctx->result, MM_CORE_ERROR, MM_CORE_ERROR_IN_PROGRESS, - "MBIM device already being opened"); - port_open_context_complete_and_free (ctx); + "MBIM device open/close operation in progress"); + port_context_complete_and_free (ctx); return; } if (self->priv->mbim_device) { g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); - port_open_context_complete_and_free (ctx); + port_context_complete_and_free (ctx); return; } fullpath = g_strdup_printf ("/dev/%s", mm_port_get_device (MM_PORT (self))); file = g_file_new_for_path (fullpath); - self->priv->opening = TRUE; + self->priv->in_progress = TRUE; mbim_device_new (file, ctx->cancellable, (GAsyncReadyCallback)mbim_device_new_ready, @@ -145,6 +159,8 @@ mm_mbim_port_open (MMMbimPort *self, g_object_unref (file); } +/*****************************************************************************/ + gboolean mm_mbim_port_is_open (MMMbimPort *self) { @@ -153,35 +169,66 @@ mm_mbim_port_is_open (MMMbimPort *self) return !!self->priv->mbim_device; } +/*****************************************************************************/ + +gboolean +mm_mbim_port_close_finish (MMMbimPort *self, + GAsyncResult *res, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); +} + static void mbim_device_close_ready (MbimDevice *device, - GAsyncResult *res) + GAsyncResult *res, + PortContext *ctx) { GError *error = NULL; - if (!mbim_device_close_finish (device, res, &error)) { - mm_warn ("Couldn't properly close MBIM device: %s", - error->message); - g_error_free (error); - } + if (!mbim_device_close_finish (device, res, &error)) + g_simple_async_result_take_error (ctx->result, error); + else + g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + + ctx->self->priv->in_progress = FALSE; + g_clear_object (&ctx->self->priv->mbim_device); + + port_context_complete_and_free (ctx); } void -mm_mbim_port_close (MMMbimPort *self) +mm_mbim_port_close (MMMbimPort *self, + GAsyncReadyCallback callback, + gpointer user_data) { + PortContext *ctx; + g_return_if_fail (MM_IS_MBIM_PORT (self)); - if (!self->priv->mbim_device) + ctx = port_context_new (self, NULL, callback, user_data); + + if (self->priv->in_progress) { + g_simple_async_result_set_error (ctx->result, + MM_CORE_ERROR, + MM_CORE_ERROR_IN_PROGRESS, + "MBIM device open/close operation in progress"); + port_context_complete_and_free (ctx); + return; + } + + if (!self->priv->mbim_device) { + g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + port_context_complete_and_free (ctx); return; + } - /* Close and release the device. This method is async, - * but we don't really care about the result. */ + self->priv->in_progress = TRUE; mbim_device_close (self->priv->mbim_device, 5, NULL, (GAsyncReadyCallback)mbim_device_close_ready, - NULL); - + ctx); g_clear_object (&self->priv->mbim_device); } diff --git a/src/mm-mbim-port.h b/src/mm-mbim-port.h index 0a18663e..c9c16c3b 100644 --- a/src/mm-mbim-port.h +++ b/src/mm-mbim-port.h @@ -48,15 +48,20 @@ GType mm_mbim_port_get_type (void); MMMbimPort *mm_mbim_port_new (const gchar *name); -void mm_mbim_port_open (MMMbimPort *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean mm_mbim_port_open_finish (MMMbimPort *self, - GAsyncResult *res, - GError **error); -gboolean mm_mbim_port_is_open (MMMbimPort *self); -void mm_mbim_port_close (MMMbimPort *self); +void mm_mbim_port_open (MMMbimPort *self, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mm_mbim_port_open_finish (MMMbimPort *self, + GAsyncResult *res, + GError **error); +gboolean mm_mbim_port_is_open (MMMbimPort *self); +void mm_mbim_port_close (MMMbimPort *self, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mm_mbim_port_close_finish (MMMbimPort *self, + GAsyncResult *res, + GError **error); MbimDevice *mm_mbim_port_peek_device (MMMbimPort *self); diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c index 5e39373e..76487534 100644 --- a/src/mm-port-probe.c +++ b/src/mm-port-probe.c @@ -345,8 +345,8 @@ port_probe_run_task_free (PortProbeRunTask *task) #if defined WITH_MBIM if (task->mbim_port) { - if (mm_mbim_port_is_open (task->mbim_port)) - mm_mbim_port_close (task->mbim_port); + /* We should have closed it cleanly before */ + g_assert (!mm_mbim_port_is_open (task->mbim_port)); g_object_unref (task->mbim_port); } #endif @@ -469,9 +469,22 @@ wdm_probe_qmi (MMPortProbe *self) #if defined WITH_MBIM static void +mbim_port_close_ready (MMMbimPort *mbim_port, + GAsyncResult *res, + MMPortProbe *self) +{ + PortProbeRunTask *task = self->priv->task; + + mm_mbim_port_close_finish (mbim_port, res, NULL); + + /* Keep on */ + task->source_id = g_idle_add ((GSourceFunc)wdm_probe, self); +} + +static void mbim_port_open_ready (MMMbimPort *mbim_port, - GAsyncResult *res, - MMPortProbe *self) + GAsyncResult *res, + MMPortProbe *self) { PortProbeRunTask *task = self->priv->task; GError *error = NULL; @@ -489,10 +502,9 @@ mbim_port_open_ready (MMMbimPort *mbim_port, /* Set probing result */ mm_port_probe_set_result_mbim (self, is_mbim); - mm_mbim_port_close (mbim_port); - - /* Keep on */ - task->source_id = g_idle_add ((GSourceFunc)wdm_probe, self); + mm_mbim_port_close (task->mbim_port, + (GAsyncReadyCallback)mbim_port_close_ready, + self); } static gboolean |