[glib] ginitable: Relax idempotency requirements on init() and init_async()



commit deab64365166fd3367a928306df0987b176fc3f7
Author: Philip Withnall <philip withnall collabora co uk>
Date:   Wed Jun 15 11:25:19 2016 -0400

    ginitable: Relax idempotency requirements on init() and init_async()
    
    The previously documented requirements for implementing init() and
    init_async() as completely idempotent were really quite hard to achieve,
    and brought a lot of pain for very little gain. Many implementations of
    GInitable and GAsyncInitable did not actually follow the requirements,
    or did not correctly handle concurrent init_async() calls.
    
    Relax those requirements so that classes can decide whether their init()
    or init_async() implementations need to be idempotent.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=766660

 gio/gasyncinitable.c |   13 ++++++++-----
 gio/ginitable.c      |   26 +++++++++++++++++++++-----
 2 files changed, 29 insertions(+), 10 deletions(-)
---
diff --git a/gio/gasyncinitable.c b/gio/gasyncinitable.c
index 827bffc..2994329 100644
--- a/gio/gasyncinitable.c
+++ b/gio/gasyncinitable.c
@@ -166,6 +166,9 @@ g_async_initable_default_init (GAsyncInitableInterface *iface)
  * initial construction. If the object also implements #GInitable you can
  * optionally call g_initable_init() instead.
  *
+ * This method is intended for language bindings. If writing in C,
+ * g_async_initable_new_async() should typically be used instead.
+ *
  * When the initialization is finished, @callback will be called. You can
  * then call g_async_initable_init_finish() to get the result of the
  * initialization.
@@ -183,11 +186,11 @@ g_async_initable_default_init (GAsyncInitableInterface *iface)
  * have undefined behaviour. They will often fail with g_critical() or
  * g_warning(), but this must not be relied on.
  *
- * Implementations of this method must be idempotent: i.e. multiple calls
- * to this function with the same argument should return the same results.
- * Only the first call initializes the object; further calls return the result
- * of the first call. This is so that it's safe to implement the singleton
- * pattern in the GObject constructor function.
+ * Callers should not assume that a class which implements #GAsyncInitable can
+ * be initialized multiple times; for more information, see g_initable_init().
+ * If a class explicitly supports being initialized multiple times,
+ * implementation requires yielding all subsequent calls to init_async() on the
+ * results of the first call.
  *
  * For classes that also support the #GInitable interface, the default
  * implementation of this method will run the g_initable_init() function
diff --git a/gio/ginitable.c b/gio/ginitable.c
index 92cf3ff..f52046b 100644
--- a/gio/ginitable.c
+++ b/gio/ginitable.c
@@ -72,6 +72,9 @@ g_initable_default_init (GInitableInterface *iface)
  *
  * Initializes the object implementing the interface.
  *
+ * This method is intended for language bindings. If writing in C,
+ * g_initable_new() should typically be used instead.
+ *
  * The object must be initialized before any real use after initial
  * construction, either with this function or g_async_initable_init_async().
  *
@@ -87,11 +90,24 @@ g_initable_default_init (GInitableInterface *iface)
  * g_object_unref() are considered to be invalid, and have undefined
  * behaviour. See the [introduction][ginitable] for more details.
  *
- * Implementations of this method must be idempotent, i.e. multiple calls
- * to this function with the same argument should return the same results.
- * Only the first call initializes the object, further calls return the result
- * of the first call. This is so that it's safe to implement the singleton
- * pattern in the GObject constructor function.
+ * Callers should not assume that a class which implements #GInitable can be
+ * initialized multiple times, unless the class explicitly documents itself as
+ * supporting this. Generally, a class’ implementation of init() can assume
+ * (and assert) that it will only be called once. Previously, this documentation
+ * recommended all #GInitable implementations should be idempotent; that
+ * recommendation was relaxed in GLib 2.54.
+ *
+ * If a class explicitly supports being initialized multiple times, it is
+ * recommended that the method is idempotent: multiple calls with the same
+ * arguments should return the same results. Only the first call initializes
+ * the object; further calls return the result of the first call.
+ *
+ * One reason why a class might need to support idempotent initialization is if
+ * it is designed to be used via the singleton pattern, with a
+ * #GObjectClass.constructor that sometimes returns an existing instance.
+ * In this pattern, a caller would expect to be able to call g_initable_init()
+ * on the result of g_object_new(), regardless of whether it is in fact a new
+ * instance.
  *
  * Returns: %TRUE if successful. If an error has occurred, this function will
  *     return %FALSE and set @error appropriately if present.


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