port-qmi: asynchronous close operation always

To be in sync with the qmi_device_close_async() underlying method,
given that the synchronous one is deprecated.
This commit is contained in:
Aleksander Morgado
2020-01-22 13:04:32 +01:00
parent bf76fcd526
commit 377691afd4
6 changed files with 133 additions and 40 deletions

View File

@@ -1584,6 +1584,14 @@ finalize (GObject *object)
G_OBJECT_CLASS (mm_base_modem_parent_class)->finalize (object); G_OBJECT_CLASS (mm_base_modem_parent_class)->finalize (object);
} }
#if defined WITH_QMI
static void
foreach_port_qmi_close (MMPortQmi *port_qmi)
{
mm_port_qmi_close (port_qmi, NULL, NULL);
}
#endif
#if defined WITH_MBIM #if defined WITH_MBIM
static void static void
foreach_port_mbim_close (MMPortMbim *port_mbim) foreach_port_mbim_close (MMPortMbim *port_mbim)
@@ -1623,7 +1631,7 @@ dispose (GObject *object)
* otherwise the allocated CIDs will be kept allocated, and if we end up * otherwise the allocated CIDs will be kept allocated, and if we end up
* allocating too many newer allocations will fail with client-ids-exhausted * allocating too many newer allocations will fail with client-ids-exhausted
* errors. */ * errors. */
g_list_foreach (self->priv->qmi, (GFunc)mm_port_qmi_close, NULL); g_list_foreach (self->priv->qmi, (GFunc)foreach_port_qmi_close, NULL);
g_list_free_full (self->priv->qmi, g_object_unref); g_list_free_full (self->priv->qmi, g_object_unref);
self->priv->qmi = NULL; self->priv->qmi = NULL;
#endif #endif

View File

@@ -481,7 +481,7 @@ connect_context_free (ConnectContext *ctx)
} }
if (ctx->explicit_qmi_open) if (ctx->explicit_qmi_open)
mm_port_qmi_close (ctx->qmi); mm_port_qmi_close (ctx->qmi, NULL, NULL);
g_clear_error (&ctx->error_ipv4); g_clear_error (&ctx->error_ipv4);
g_clear_error (&ctx->error_ipv6); g_clear_error (&ctx->error_ipv6);
@@ -1883,7 +1883,7 @@ reset_bearer_connection (MMBearerQmi *self,
if (self->priv->qmi) { if (self->priv->qmi) {
if (self->priv->explicit_qmi_open) { if (self->priv->explicit_qmi_open) {
self->priv->explicit_qmi_open = FALSE; self->priv->explicit_qmi_open = FALSE;
mm_port_qmi_close (self->priv->qmi); mm_port_qmi_close (self->priv->qmi, NULL, NULL);
} }
g_clear_object (&self->priv->qmi); g_clear_object (&self->priv->qmi);
} }

View File

@@ -8651,7 +8651,7 @@ dispose (GObject *object)
untrack_qmi_device_removed (self, qmi); untrack_qmi_device_removed (self, qmi);
/* If we did open the QMI port during initialization, close it now */ /* If we did open the QMI port during initialization, close it now */
if (mm_port_qmi_is_open (qmi)) if (mm_port_qmi_is_open (qmi))
mm_port_qmi_close (qmi); mm_port_qmi_close (qmi, NULL, NULL);
} }
g_list_free_full (self->priv->firmware_list, g_object_unref); g_list_free_full (self->priv->firmware_list, g_object_unref);

View File

@@ -435,8 +435,8 @@ port_probe_run_context_free (PortProbeRunContext *ctx)
#if defined WITH_QMI #if defined WITH_QMI
if (ctx->port_qmi) { if (ctx->port_qmi) {
if (mm_port_qmi_is_open (ctx->port_qmi)) /* We should have closed it cleanly before */
mm_port_qmi_close (ctx->port_qmi); g_assert (!mm_port_qmi_is_open (ctx->port_qmi));
g_object_unref (ctx->port_qmi); g_object_unref (ctx->port_qmi);
} }
#endif #endif
@@ -464,6 +464,22 @@ static gboolean wdm_probe (MMPortProbe *self);
#if defined WITH_QMI #if defined WITH_QMI
static void
qmi_port_close_ready (MMPortQmi *qmi_port,
GAsyncResult *res,
MMPortProbe *self)
{
PortProbeRunContext *ctx;
g_assert (self->priv->task);
ctx = g_task_get_task_data (self->priv->task);
mm_port_qmi_close_finish (qmi_port, res, NULL);
/* Keep on */
ctx->source_id = g_idle_add ((GSourceFunc) wdm_probe, self);
}
static void static void
port_qmi_open_ready (MMPortQmi *port_qmi, port_qmi_open_ready (MMPortQmi *port_qmi,
GAsyncResult *res, GAsyncResult *res,
@@ -487,10 +503,10 @@ port_qmi_open_ready (MMPortQmi *port_qmi,
/* Set probing result */ /* Set probing result */
mm_port_probe_set_result_qmi (self, is_qmi); mm_port_probe_set_result_qmi (self, is_qmi);
mm_port_qmi_close (port_qmi);
/* Keep on */ mm_port_qmi_close (ctx->port_qmi,
ctx->source_id = g_idle_add ((GSourceFunc) wdm_probe, self); (GAsyncReadyCallback) qmi_port_close_ready,
self);
} }
#endif /* WITH_QMI */ #endif /* WITH_QMI */

View File

@@ -33,7 +33,7 @@ typedef struct {
} ServiceInfo; } ServiceInfo;
struct _MMPortQmiPrivate { struct _MMPortQmiPrivate {
gboolean opening; gboolean in_progress;
QmiDevice *qmi_device; QmiDevice *qmi_device;
GList *services; GList *services;
gboolean llp_is_raw_ip; gboolean llp_is_raw_ip;
@@ -244,7 +244,7 @@ port_open_complete_with_error (GTask *task)
ctx = g_task_get_task_data (task); ctx = g_task_get_task_data (task);
g_assert (ctx->error); g_assert (ctx->error);
self->priv->opening = FALSE; self->priv->in_progress = FALSE;
g_task_return_error (task, g_steal_pointer (&ctx->error)); g_task_return_error (task, g_steal_pointer (&ctx->error));
g_object_unref (task); g_object_unref (task);
} }
@@ -401,11 +401,11 @@ port_open_step (GTask *task)
case PORT_OPEN_STEP_CHECK_OPENING: case PORT_OPEN_STEP_CHECK_OPENING:
mm_dbg ("Checking if QMI device already opening..."); mm_dbg ("Checking if QMI device already opening...");
if (self->priv->opening) { if (self->priv->in_progress) {
g_task_return_new_error (task, g_task_return_new_error (task,
MM_CORE_ERROR, MM_CORE_ERROR,
MM_CORE_ERROR_IN_PROGRESS, MM_CORE_ERROR_IN_PROGRESS,
"QMI device already being opened"); "QMI device open/close operation in progress");
g_object_unref (task); g_object_unref (task);
return; return;
} }
@@ -432,7 +432,7 @@ port_open_step (GTask *task)
/* We flag in this point that we're opening. From now on, if we stop /* We flag in this point that we're opening. From now on, if we stop
* for whatever reason, we should clear this flag. We do this by ensuring * for whatever reason, we should clear this flag. We do this by ensuring
* that all callbacks go through the LAST step for completing. */ * that all callbacks go through the LAST step for completing. */
self->priv->opening = TRUE; self->priv->in_progress = TRUE;
mm_dbg ("Creating QMI device..."); mm_dbg ("Creating QMI device...");
qmi_device_new (file, qmi_device_new (file,
@@ -585,8 +585,8 @@ port_open_step (GTask *task)
/* Store device in private info */ /* Store device in private info */
g_assert (ctx->device); g_assert (ctx->device);
g_assert (!self->priv->qmi_device); g_assert (!self->priv->qmi_device);
self->priv->qmi_device = g_steal_pointer (&ctx->device); self->priv->qmi_device = g_object_ref (ctx->device);
self->priv->opening = FALSE; self->priv->in_progress = FALSE;
g_task_return_boolean (task, TRUE); g_task_return_boolean (task, TRUE);
g_object_unref (task); g_object_unref (task);
return; return;
@@ -617,6 +617,8 @@ mm_port_qmi_open (MMPortQmi *self,
port_open_step (task); port_open_step (task);
} }
/*****************************************************************************/
gboolean gboolean
mm_port_qmi_is_open (MMPortQmi *self) mm_port_qmi_is_open (MMPortQmi *self)
{ {
@@ -625,23 +627,88 @@ mm_port_qmi_is_open (MMPortQmi *self)
return !!self->priv->qmi_device; return !!self->priv->qmi_device;
} }
void /*****************************************************************************/
mm_port_qmi_close (MMPortQmi *self)
typedef struct {
QmiDevice *qmi_device;
} PortQmiCloseContext;
static void
port_qmi_close_context_free (PortQmiCloseContext *ctx)
{
g_clear_object (&ctx->qmi_device);
g_slice_free (PortQmiCloseContext, ctx);
}
gboolean
mm_port_qmi_close_finish (MMPortQmi *self,
GAsyncResult *res,
GError **error)
{
return g_task_propagate_boolean (G_TASK (res), error);
}
static void
qmi_device_close_ready (QmiDevice *qmi_device,
GAsyncResult *res,
GTask *task)
{ {
GList *l;
GError *error = NULL; GError *error = NULL;
MMPortQmi *self;
self = g_task_get_source_object (task);
g_assert (!self->priv->qmi_device);
self->priv->in_progress = FALSE;
if (!qmi_device_close_finish (qmi_device, res, &error))
g_task_return_error (task, error);
else
g_task_return_boolean (task, TRUE);
g_object_unref (task);
}
void
mm_port_qmi_close (MMPortQmi *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
PortQmiCloseContext *ctx;
GTask *task;
GList *l;
g_return_if_fail (MM_IS_PORT_QMI (self)); g_return_if_fail (MM_IS_PORT_QMI (self));
if (!self->priv->qmi_device) task = g_task_new (self, NULL, callback, user_data);
if (self->priv->in_progress) {
g_task_return_new_error (task,
MM_CORE_ERROR,
MM_CORE_ERROR_IN_PROGRESS,
"QMI device open/close operation in progress");
g_object_unref (task);
return; return;
}
if (!self->priv->qmi_device) {
g_task_return_boolean (task, TRUE);
g_object_unref (task);
return;
}
self->priv->in_progress = TRUE;
/* Store device to close in the context */
ctx = g_slice_new0 (PortQmiCloseContext);
ctx->qmi_device = g_steal_pointer (&self->priv->qmi_device);
g_task_set_task_data (task, ctx, (GDestroyNotify)port_qmi_close_context_free);
/* Release all allocated clients */ /* Release all allocated clients */
for (l = self->priv->services; l; l = g_list_next (l)) { for (l = self->priv->services; l; l = g_list_next (l)) {
ServiceInfo *info = l->data; ServiceInfo *info = l->data;
mm_dbg ("Releasing client for service '%s'...", qmi_service_get_string (info->service)); mm_dbg ("Releasing client for service '%s'...", qmi_service_get_string (info->service));
qmi_device_release_client (self->priv->qmi_device, qmi_device_release_client (ctx->qmi_device,
info->client, info->client,
QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID, QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID,
3, NULL, NULL, NULL); 3, NULL, NULL, NULL);
@@ -650,14 +717,11 @@ mm_port_qmi_close (MMPortQmi *self)
g_list_free_full (self->priv->services, g_free); g_list_free_full (self->priv->services, g_free);
self->priv->services = NULL; self->priv->services = NULL;
/* Close and release the device */ qmi_device_close_async (ctx->qmi_device,
if (!qmi_device_close (self->priv->qmi_device, &error)) { 5,
mm_warn ("Couldn't properly close QMI device: %s", NULL,
error->message); (GAsyncReadyCallback)qmi_device_close_ready,
g_error_free (error); task);
}
g_clear_object (&self->priv->qmi_device);
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -57,7 +57,12 @@ gboolean mm_port_qmi_open_finish (MMPortQmi *self,
GAsyncResult *res, GAsyncResult *res,
GError **error); GError **error);
gboolean mm_port_qmi_is_open (MMPortQmi *self); gboolean mm_port_qmi_is_open (MMPortQmi *self);
void mm_port_qmi_close (MMPortQmi *self); void mm_port_qmi_close (MMPortQmi *self,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean mm_port_qmi_close_finish (MMPortQmi *self,
GAsyncResult *res,
GError **error);
typedef enum { typedef enum {
MM_PORT_QMI_FLAG_DEFAULT = 0, MM_PORT_QMI_FLAG_DEFAULT = 0,