[libsecret/wip/dueno/gtask-dup-error] Properly chain-up GTasks around GDBusProxy::init_async




commit d768ce4efeb5c726ddfed2d1c1c060454ce20a81
Author: Daiki Ueno <dueno src gnome org>
Date:   Sun May 8 09:32:23 2022 +0200

    Properly chain-up GTasks around GDBusProxy::init_async
    
    Our GAsyncInitable implementations in SecretService, SecretCollection,
    and SecretItem internally wrap GDBusProxy::init_async and perform
    additional error processing. To chain up we used to pass around a
    single GTask, which caused an issue in the (additional) error path:
    GDBusProxy::init_async may have already called
    g_task_return_boolean(task, TRUE) and in that case GLib produces the
    following warning:
    
      g_task_return_error: assertion '!task->ever_returned' failed
    
    This fixes the issue by creating a temporary GTask around
    GDBusProxy::init_async call.
    
    Signed-off-by: Daiki Ueno <dueno src gnome org>

 libsecret/secret-collection.c | 30 +++++++++++++++++++++++++++---
 libsecret/secret-item.c       | 30 +++++++++++++++++++++++++++---
 libsecret/secret-service.c    | 37 +++++++++++++++++++++++++++++++------
 3 files changed, 85 insertions(+), 12 deletions(-)
---
diff --git a/libsecret/secret-collection.c b/libsecret/secret-collection.c
index 5f40632..0ce32a5 100644
--- a/libsecret/secret-collection.c
+++ b/libsecret/secret-collection.c
@@ -625,17 +625,35 @@ on_init_service (GObject *source,
        g_clear_object (&task);
 }
 
+typedef struct {
+       GAsyncReadyCallback callback;
+       gpointer user_data;
+} InitBaseClosure;
+
+static void
+secret_collection_async_initable_init_async (GAsyncInitable *initable,
+                                             int io_priority,
+                                             GCancellable *cancellable,
+                                             GAsyncReadyCallback callback,
+                                             gpointer user_data);
+
 static void
 on_init_base (GObject *source,
               GAsyncResult *result,
               gpointer user_data)
 {
-       GTask *task = G_TASK (user_data);
-       GCancellable *cancellable = g_task_get_cancellable (task);
+       GTask *base_task = G_TASK (user_data);
+       InitBaseClosure *base = g_task_get_task_data (base_task);
+       GCancellable *cancellable = g_task_get_cancellable (base_task);
+       GTask *task;
        SecretCollection *self = SECRET_COLLECTION (source);
        GDBusProxy *proxy = G_DBUS_PROXY (self);
        GError *error = NULL;
 
+       task = g_task_new (source, cancellable, base->callback, base->user_data);
+       g_task_set_source_tag (task, secret_collection_async_initable_init_async);
+       g_clear_object (&base_task);
+
        if (!secret_collection_async_initable_parent_iface->init_finish (G_ASYNC_INITABLE (self),
                                                                         result, &error)) {
                g_task_return_error (task, g_steal_pointer (&error));
@@ -665,10 +683,16 @@ secret_collection_async_initable_init_async (GAsyncInitable *initable,
                                              gpointer user_data)
 {
        GTask *task;
+       InitBaseClosure *base;
 
-       task = g_task_new (initable, cancellable, callback, user_data);
+       task = g_task_new (initable, cancellable, NULL, NULL);
        g_task_set_source_tag (task, secret_collection_async_initable_init_async);
 
+       base = g_new0 (InitBaseClosure, 1);
+       base->callback = callback;
+       base->user_data = user_data;
+       g_task_set_task_data (task, base, g_free);
+
        secret_collection_async_initable_parent_iface->init_async (initable,
                                                                   io_priority,
                                                                   cancellable,
diff --git a/libsecret/secret-item.c b/libsecret/secret-item.c
index 6773c4b..6703b20 100644
--- a/libsecret/secret-item.c
+++ b/libsecret/secret-item.c
@@ -512,17 +512,35 @@ on_init_service (GObject *source,
        g_clear_object (&task);
 }
 
+typedef struct {
+       GAsyncReadyCallback callback;
+       gpointer user_data;
+} InitBaseClosure;
+
+static void
+secret_item_async_initable_init_async (GAsyncInitable *initable,
+                                       int io_priority,
+                                       GCancellable *cancellable,
+                                       GAsyncReadyCallback callback,
+                                       gpointer user_data);
+
 static void
 on_init_base (GObject *source,
               GAsyncResult *result,
               gpointer user_data)
 {
-       GTask *task = G_TASK (user_data);
-       GCancellable *cancellable = g_task_get_cancellable (task);
+       GTask *base_task = G_TASK (user_data);
+       InitBaseClosure *base = g_task_get_task_data (base_task);
+       GCancellable *cancellable = g_task_get_cancellable (base_task);
+       GTask *task;
        SecretItem *self = SECRET_ITEM (source);
        GDBusProxy *proxy = G_DBUS_PROXY (self);
        GError *error = NULL;
 
+       task = g_task_new (source, cancellable, base->callback, base->user_data);
+       g_task_set_source_tag (task, secret_item_async_initable_init_async);
+       g_clear_object (&base_task);
+
        if (!secret_item_async_initable_parent_iface->init_finish (G_ASYNC_INITABLE (self),
                                                                   result, &error)) {
                g_task_return_error (task, g_steal_pointer (&error));
@@ -552,10 +570,16 @@ secret_item_async_initable_init_async (GAsyncInitable *initable,
                                        gpointer user_data)
 {
        GTask *task;
+       InitBaseClosure *base;
 
-       task = g_task_new (initable, cancellable, callback, user_data);
+       task = g_task_new (initable, cancellable, NULL, NULL);
        g_task_set_source_tag (task, secret_item_async_initable_init_async);
 
+       base = g_new0 (InitBaseClosure, 1);
+       base->callback = callback;
+       base->user_data = user_data;
+       g_task_set_task_data (task, base, g_free);
+
        secret_item_async_initable_parent_iface->init_async (initable, io_priority,
                                                             cancellable,
                                                             on_init_base,
diff --git a/libsecret/secret-service.c b/libsecret/secret-service.c
index aabbac7..d535f07 100644
--- a/libsecret/secret-service.c
+++ b/libsecret/secret-service.c
@@ -717,18 +717,41 @@ secret_service_initable_iface (GInitableIface *iface)
        iface->init = secret_service_initable_init;
 }
 
+static void
+secret_service_async_initable_init_async (GAsyncInitable *initable,
+                                          int io_priority,
+                                          GCancellable *cancellable,
+                                          GAsyncReadyCallback callback,
+                                          gpointer user_data);
+
+typedef struct {
+       GAsyncReadyCallback callback;
+       gpointer user_data;
+} InitBaseClosure;
+
 static void
 on_init_base (GObject *source,
               GAsyncResult *result,
               gpointer user_data)
 {
-       GTask *task = G_TASK (user_data);
+       GTask *base_task = G_TASK (user_data);
+       InitBaseClosure *base = g_task_get_task_data (base_task);
+       GCancellable *cancellable = g_task_get_cancellable (base_task);
+       GTask *task;
+       InitClosure *init;
        SecretService *self = SECRET_SERVICE (source);
        GError *error = NULL;
 
+       task = g_task_new (source, cancellable, base->callback, base->user_data);
+       g_task_set_source_tag (task, secret_service_async_initable_init_async);
+       init = g_slice_new0 (InitClosure);
+       g_task_set_task_data (task, init, init_closure_free);
+
+       g_clear_object (&base_task);
+
        if (!secret_service_async_initable_parent_iface->init_finish (G_ASYNC_INITABLE (self),
                                                                      result, &error)) {
-               g_task_return_error (task, error);
+               g_task_return_error (task, g_steal_pointer (&error));
        } else {
                service_ensure_for_flags_async (self, self->pv->init_flags, task);
        }
@@ -744,12 +767,14 @@ secret_service_async_initable_init_async (GAsyncInitable *initable,
                                           gpointer user_data)
 {
        GTask *task;
-       InitClosure *closure;
+       InitBaseClosure *base;
 
-       task = g_task_new (initable, cancellable, callback, user_data);
+       task = g_task_new (initable, cancellable, NULL, NULL);
        g_task_set_source_tag (task, secret_service_async_initable_init_async);
-       closure = g_slice_new0 (InitClosure);
-       g_task_set_task_data (task, closure, init_closure_free);
+       base = g_new0 (InitBaseClosure, 1);
+       base->callback = callback;
+       base->user_data = user_data;
+       g_task_set_task_data (task, base, g_free);
 
        secret_service_async_initable_parent_iface->init_async (initable,
                                                                io_priority,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]