about summary refs log tree commit diff
path: root/clients/cloud-setup/nmcs-provider.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2021-02-11 18:11:46 +0100
committerMichael Biebl <biebl@debian.org>2021-02-11 18:11:46 +0100
commit80ec1decc49c72efec2a8b87c06245c92c0ab807 (patch)
treee3b229aa94e8dcf0590f2317664176e7b8f7607b /clients/cloud-setup/nmcs-provider.c
parent65f86e8f56267192d42f2b629fc6b0c99fb9cd0c (diff)
New upstream version 1.29.90 upstream/1.29.90
Diffstat (limited to 'clients/cloud-setup/nmcs-provider.c')
-rw-r--r--clients/cloud-setup/nmcs-provider.c74
1 files changed, 65 insertions, 9 deletions
diff --git a/clients/cloud-setup/nmcs-provider.c b/clients/cloud-setup/nmcs-provider.c
index e9e79a35..c700d8e1 100644
--- a/clients/cloud-setup/nmcs-provider.c
+++ b/clients/cloud-setup/nmcs-provider.c
@@ -1,6 +1,6 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include "nm-default.h"
+#include "libnm/nm-default-client.h"
 
 #include "nmcs-provider.h"
 
@@ -114,19 +114,61 @@ _iface_data_free(gpointer data)
 }
 
 static void
-_get_config_data_free(gpointer data)
+_get_config_task_maybe_return(NMCSProviderGetConfigTaskData *get_config_data, GError *error_take)
 {
-    NMCSProviderGetConfigTaskData *get_config_data = data;
+    gs_free_error GError *error = error_take;
 
-    if (get_config_data->extra_destroy)
-        get_config_data->extra_destroy(get_config_data->extra_data);
+    nm_assert(get_config_data);
+    nm_assert(G_IS_TASK(get_config_data->task));
+
+    if (!error) {
+        if (get_config_data->n_pending > 0)
+            return;
+    }
+
+    g_cancellable_cancel(get_config_data->intern_cancellable);
+
+    if (error) {
+        if (nm_utils_error_is_cancelled(error))
+            _LOGD("get-config: cancelled");
+        else
+            _LOGD("get-config: failed: %s", error->message);
+        g_task_return_error(get_config_data->task, g_steal_pointer(&error));
+    } else {
+        _LOGD("get-config: success");
+        g_task_return_pointer(get_config_data->task,
+                              g_hash_table_ref(get_config_data->result_dict),
+                              (GDestroyNotify) g_hash_table_unref);
+    }
+
+    nm_clear_g_signal_handler(g_task_get_cancellable(get_config_data->task),
+                              &get_config_data->extern_cancelled_id);
+
+    if (get_config_data->extra_data_destroy)
+        get_config_data->extra_data_destroy(get_config_data->extra_data);
 
     nm_clear_pointer(&get_config_data->result_dict, g_hash_table_unref);
 
+    nm_g_object_unref(get_config_data->intern_cancellable);
+    g_object_unref(get_config_data->task);
     nm_g_slice_free(get_config_data);
 }
 
 void
+_nmcs_provider_get_config_task_maybe_return(NMCSProviderGetConfigTaskData *get_config_data,
+                                            GError *                       error_take)
+{
+    nm_assert(!error_take || !nm_utils_error_is_cancelled(error_take));
+    _get_config_task_maybe_return(get_config_data, error_take);
+}
+
+static void
+_get_config_cancelled_cb(GObject *object, gpointer user_data)
+{
+    _get_config_task_maybe_return(user_data, nm_utils_error_new_cancelled(FALSE, NULL));
+}
+
+void
 nmcs_provider_get_config(NMCSProvider *      self,
                          gboolean            any,
                          const char *const * hwaddrs,
@@ -139,6 +181,8 @@ nmcs_provider_get_config(NMCSProvider *      self,
     g_return_if_fail(NMCS_IS_PROVIDER(self));
     g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable));
 
+    _LOGD("get-config: starting");
+
     get_config_data  = g_slice_new(NMCSProviderGetConfigTaskData);
     *get_config_data = (NMCSProviderGetConfigTaskData){
         .task = nm_g_task_new(self, cancellable, nmcs_provider_get_config, callback, user_data),
@@ -146,8 +190,6 @@ nmcs_provider_get_config(NMCSProvider *      self,
         .result_dict = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, _iface_data_free),
     };
 
-    g_task_set_task_data(get_config_data->task, get_config_data, _get_config_data_free);
-
     nmcs_wait_for_objects_register(get_config_data->task);
 
     for (; hwaddrs && hwaddrs[0]; hwaddrs++) {
@@ -156,7 +198,21 @@ nmcs_provider_get_config(NMCSProvider *      self,
                             nmcs_provider_get_config_iface_data_new(TRUE));
     }
 
-    _LOGD("get-config: starting");
+    if (cancellable) {
+        gulong cancelled_id;
+
+        cancelled_id = g_cancellable_connect(cancellable,
+                                             G_CALLBACK(_get_config_cancelled_cb),
+                                             get_config_data,
+                                             NULL);
+        if (cancelled_id == 0) {
+            /* the callback was already invoked synchronously and the task already returned. */
+            return;
+        }
+
+        get_config_data->extern_cancelled_id = cancelled_id;
+        get_config_data->intern_cancellable  = g_cancellable_new();
+    }
 
     NMCS_PROVIDER_GET_CLASS(self)->get_config(self, get_config_data);
 }