From 50be73286059a9694f0cc8cc8b42d73cb6e9cb1f Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Sun, 23 May 2021 21:40:20 +0200 Subject: [PATCH 30/39] iface-modem,bearer-list: sync all bearers one after the other Do not launch N checks for N bearers and ignore their result. Instead, go one by one, and report errors one by one. --- src/mm-bearer-list.c | 86 ++++++++++++++++++++++++++++++++++++++++++++ src/mm-bearer-list.h | 11 ++++++ src/mm-iface-modem.c | 49 +++++++++++++++++++------ 3 files changed, 136 insertions(+), 10 deletions(-) diff --git a/src/mm-bearer-list.c b/src/mm-bearer-list.c index 65717132..1ce53e05 100644 --- a/src/mm-bearer-list.c +++ b/src/mm-bearer-list.c @@ -268,6 +268,92 @@ mm_bearer_list_disconnect_all_bearers (MMBearerList *self, /*****************************************************************************/ +#if defined WITH_SYSTEMD_SUSPEND_RESUME + +typedef struct { + GList *pending; + MMBaseBearer *current; +} SyncAllContext; + +static void +sync_all_context_free (SyncAllContext *ctx) +{ + if (ctx->current) + g_object_unref (ctx->current); + g_list_free_full (ctx->pending, g_object_unref); + g_free (ctx); +} + +gboolean +mm_bearer_list_sync_all_bearers_finish (MMBearerList *self, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); +} + +static void sync_next_bearer (GTask *task); + +static void +sync_ready (MMBaseBearer *bearer, + GAsyncResult *res, + GTask *task) +{ + g_autoptr(GError) error = NULL; + + if (!mm_base_bearer_sync_finish (bearer, res, &error)) + mm_obj_warn (bearer, "failed synchronizing state: %s", error->message); + + sync_next_bearer (task); +} + +static void +sync_next_bearer (GTask *task) +{ + SyncAllContext *ctx; + + ctx = g_task_get_task_data (task); + if (ctx->current) + g_clear_object (&ctx->current); + + /* No more bearers? all done! */ + if (!ctx->pending) { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } + + ctx->current = MM_BASE_BEARER (ctx->pending->data); + ctx->pending = g_list_delete_link (ctx->pending, ctx->pending); + + mm_base_bearer_sync (ctx->current, (GAsyncReadyCallback)sync_ready, task); +} + +void +mm_bearer_list_sync_all_bearers (MMBearerList *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + SyncAllContext *ctx; + GTask *task; + + ctx = g_new0 (SyncAllContext, 1); + + /* Get a copy of the list */ + ctx->pending = g_list_copy_deep (self->priv->bearers, + (GCopyFunc)g_object_ref, + NULL); + + task = g_task_new (self, NULL, callback, user_data); + g_task_set_task_data (task, ctx, (GDestroyNotify)sync_all_context_free); + + sync_next_bearer (task); +} + +#endif + +/*****************************************************************************/ + MMBearerList * mm_bearer_list_new (guint max_bearers, guint max_active_bearers) diff --git a/src/mm-bearer-list.h b/src/mm-bearer-list.h index 0d220eee..04af79e9 100644 --- a/src/mm-bearer-list.h +++ b/src/mm-bearer-list.h @@ -85,4 +85,15 @@ gboolean mm_bearer_list_disconnect_all_bearers_finish (MMBearerList *self, GAsyncResult *res, GError **error); +#if defined WITH_SYSTEMD_SUSPEND_RESUME + +void mm_bearer_list_sync_all_bearers (MMBearerList *self, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mm_bearer_list_sync_all_bearers_finish (MMBearerList *self, + GAsyncResult *res, + GError **error); + +#endif + #endif /* MM_BEARER_LIST_H */ diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c index 1fe1feff..c3722c0a 100644 --- a/src/mm-iface-modem.c +++ b/src/mm-iface-modem.c @@ -4273,19 +4273,49 @@ sync_detect_sim_swap_ready (MMIfaceModem *self, } static void -reload_bearers (MMIfaceModem *self) +sync_all_bearers_ready (MMBearerList *bearer_list, + GAsyncResult *res, + GTask *task) { - g_autoptr(MMBearerList) list = NULL; + MMIfaceModem *self; + SyncingContext *ctx; + g_autoptr (GError) error = NULL; + + self = g_task_get_source_object (task); + ctx = g_task_get_task_data (task); + + if (!mm_bearer_list_sync_all_bearers_finish (bearer_list, res, &error)) + mm_obj_warn (self, "synchronizing all bearer status failed: %s", error->message); + + /* Go on to next step */ + ctx->step++; + interface_syncing_step (task); +} + +static void +reload_bearers (GTask *task) +{ + MMIfaceModem *self; + SyncingContext *ctx; + g_autoptr(MMBearerList) bearer_list = NULL; + + self = g_task_get_source_object (task); + ctx = g_task_get_task_data (task); g_object_get (self, - MM_IFACE_MODEM_BEARER_LIST, &list, + MM_IFACE_MODEM_BEARER_LIST, &bearer_list, NULL); - if (list) { - mm_bearer_list_foreach (list, - (MMBearerListForeachFunc)mm_base_bearer_sync, - NULL); + if (!bearer_list) { + /* Go on to next step */ + ctx->step++; + interface_syncing_step (task); + return; } + + mm_bearer_list_sync_all_bearers (bearer_list, + (GAsyncReadyCallback)sync_all_bearers_ready, + task); } static void @@ -4338,9 +4368,8 @@ interface_syncing_step (GTask *task) /* * Refresh bearers. */ - reload_bearers (self); - ctx->step++; - /* fall through */ + reload_bearers (task); + return; case SYNCING_STEP_LAST: /* We are done without errors! */ -- 2.31.1