summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Trevisan (Treviño) <mail@3v1n0.net>2019-09-08 05:47:30 +0200
committerMarco Trevisan (Treviño) <mail@3v1n0.net>2019-09-10 09:28:21 +0200
commitf6975fa900de715ecc9bff00eeed87725ddf3f4f (patch)
treeed9b3a3878f45b031ce22072f7344f01ab86b017
parent04224b5a3110df0d3dba55a2ed109b6a59419410 (diff)
downloadNetworkManager-3v1n0/gtask-initables.tar.gz
cli: Use a queue to keep track of commands during client initalization3v1n0/gtask-initables
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.
-rw-r--r--clients/cli/common.c24
-rw-r--r--clients/cli/nmcli.h1
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 {