From f6975fa900de715ecc9bff00eeed87725ddf3f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Sun, 8 Sep 2019 05:47:30 +0200 Subject: cli: Use a queue to keep track of commands during client initalization If a new command was requested while a client was in the process of being created we were just requesting a new client. This was causing leak, so let's use a queue instead in such cases. --- clients/cli/common.c | 24 +++++++++++++++--------- clients/cli/nmcli.h | 1 + 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/clients/cli/common.c b/clients/cli/common.c index 62c94c5402..32ccbb8441 100644 --- a/clients/cli/common.c +++ b/clients/cli/common.c @@ -1218,7 +1218,6 @@ typedef struct { const NMCCommand *cmd; int argc; char **argv; - GTask *task; } CmdCall; static void @@ -1228,22 +1227,25 @@ static void got_client (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; - CmdCall *call = user_data; - NmCli *nmc = g_task_get_task_data (call->task); + GTask *task = user_data; + NmCli *nmc = g_task_get_task_data (task); nmc->should_wait--; nmc->client = nm_client_new_finish (res, &error); if (!nmc->client) { - g_task_return_new_error (call->task, NMCLI_ERROR, NMC_RESULT_ERROR_UNKNOWN, + g_task_return_new_error (task, NMCLI_ERROR, NMC_RESULT_ERROR_UNKNOWN, _("Error: Could not create NMClient object: %s."), error->message); g_error_free (error); } else { - call_cmd (nmc, call->task, call->cmd, call->argc, call->argv); + while (!g_queue_is_empty (nmc->waiting_calls)) { + CmdCall *call = g_queue_pop_head (nmc->waiting_calls); + call_cmd (nmc, task, call->cmd, call->argc, call->argv); + g_slice_free (CmdCall, call); + } + nm_clear_pointer (&nmc->waiting_calls, g_queue_free); } - - g_slice_free (CmdCall, call); } static void @@ -1262,13 +1264,17 @@ call_cmd (NmCli *nmc, GTask *task, const NMCCommand *cmd, int argc, char **argv) g_task_return_boolean (task, TRUE); g_object_unref (task); } else { + if (!nmc->waiting_calls) { + nmc->waiting_calls = g_queue_new (); + nm_client_new_async (NULL, got_client, task); + } nmc->should_wait++; + call = g_slice_new0 (CmdCall); call->cmd = cmd; call->argc = argc; call->argv = argv; - call->task = task; - nm_client_new_async (NULL, got_client, call); + g_queue_push_tail (nmc->waiting_calls, call); } } diff --git a/clients/cli/nmcli.h b/clients/cli/nmcli.h index 1c4b4a2d89..a80d31e7ba 100644 --- a/clients/cli/nmcli.h +++ b/clients/cli/nmcli.h @@ -134,6 +134,7 @@ typedef struct _NmCli { struct _NMPolkitListener *pk_listener; /* polkit agent listener */ int should_wait; /* Semaphore indicating whether nmcli should not end or not yet */ + GQueue *waiting_calls; /* Calls queued until we didn't get a client */ gboolean nowait_flag; /* '--nowait' option; used for passing to callbacks */ gboolean mode_specified; /* Whether tabular/multiline mode was specified via '--mode' option */ union { -- cgit v1.2.1