GAsyncInitable

gio.async_initable.AsyncInitable is an interface for asynchronously initializable objects.

This is the asynchronous version of gio.initable.Initable; it behaves the same in all ways except that initialization is asynchronous. For more details see the descriptions on gio.initable.Initable.

A class may implement both the gio.initable.Initable and gio.async_initable.AsyncInitable interfaces.

Users of objects implementing this are not intended to use the interface method directly; instead it will be used automatically in various ways. For C applications you generally just call gio.async_initable.AsyncInitable.newAsync directly, or indirectly via a foo_thing_new_async() wrapper. This will call gio.async_initable.AsyncInitable.initAsync under the covers, calling back with NULL and a set glib.error.ErrorG on failure.

A typical implementation might look something like this:

1 enum {
2    NOT_INITIALIZED,
3    INITIALIZING,
4    INITIALIZED
5 };
6 
7 static void
8 _foo_ready_cb (Foo *self)
9 {
10   GList *l;
11 
12   self->priv->state = INITIALIZED;
13 
14   for (l = self->priv->init_results; l != NULL; l = l->next)
15     {
16       GTask *task = l->data;
17 
18       if (self->priv->success)
19         g_task_return_boolean (task, TRUE);
20       else
21         g_task_return_new_error (task, ...);
22       g_object_unref (task);
23     }
24 
25   g_list_free (self->priv->init_results);
26   self->priv->init_results = NULL;
27 }
28 
29 static void
30 foo_init_async (GAsyncInitable       *initable,
31                 int                   io_priority,
32                 GCancellable         *cancellable,
33                 GAsyncReadyCallback   callback,
34                 gpointer              user_data)
35 {
36   Foo *self = FOO (initable);
37   GTask *task;
38 
39   task = g_task_new (initable, cancellable, callback, user_data);
40   g_task_set_name (task, G_STRFUNC);
41 
42   switch (self->priv->state)
43     {
44       case NOT_INITIALIZED:
45         _foo_get_ready (self);
46         self->priv->init_results = g_list_append (self->priv->init_results,
47                                                   task);
48         self->priv->state = INITIALIZING;
49         break;
50       case INITIALIZING:
51         self->priv->init_results = g_list_append (self->priv->init_results,
52                                                   task);
53         break;
54       case INITIALIZED:
55         if (!self->priv->success)
56           g_task_return_new_error (task, ...);
57         else
58           g_task_return_boolean (task, TRUE);
59         g_object_unref (task);
60         break;
61     }
62 }
63 
64 static gboolean
65 foo_init_finish (GAsyncInitable       *initable,
66                  GAsyncResult         *result,
67                  GError              **error)
68 {
69   g_return_val_if_fail (g_task_is_valid (result, initable), FALSE);
70 
71   return g_task_propagate_boolean (G_TASK (result), error);
72 }
73 
74 static void
75 foo_async_initable_iface_init (gpointer g_iface,
76                                gpointer data)
77 {
78   GAsyncInitableIface *iface = g_iface;
79 
80   iface->init_async = foo_init_async;
81   iface->init_finish = foo_init_finish;
82 }
struct GAsyncInitable