aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2013-04-11 19:21:21 +0200
committerAleksander Morgado <aleksander@lanedo.com>2013-04-17 15:19:39 +0200
commit659d942c33767d44f2470aee183b0eb0fc268016 (patch)
treea227fb54afab8b94c948a1a205a6363ae73ca2f6
parentd1d5616ca5607836fc2a17024555ef2578bb6d8e (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.c5
-rw-r--r--src/mm-mbim-port.c117
-rw-r--r--src/mm-mbim-port.h23
-rw-r--r--src/mm-port-probe.c28
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