+/**
+ * GWeakRef:
+ *
+ * A structure containing a weak reference to a #GObject. It can either
+ * be empty (i.e. point to %NULL), or point to an object for as long as
+ * at least one "strong" reference to that object exists. Before the
+ * object's #GObjectClass.dispose method is called, every #GWeakRef
+ * associated with becomes empty (i.e. points to %NULL).
+ *
+ * Like #GValue, #GWeakRef can be statically allocated, stack- or
+ * heap-allocated, or embedded in larger structures.
+ *
+ * Unlike g_object_weak_ref() and g_object_add_weak_pointer(), this weak
+ * reference is thread-safe: converting a weak pointer to a reference is
+ * atomic with respect to invalidation of weak pointers to destroyed
+ * objects.
+ *
+ * If the object's #GObjectClass.dispose method results in additional
+ * references to the object being held, any #GWeakRef<!-- -->s taken
+ * before it was disposed will continue to point to %NULL. If
+ * #GWeakRef<!-- -->s are taken after the object is disposed and
+ * re-referenced, they will continue to point to it until its refcount
+ * goes back to zero, at which point they too will be invalidated.
+ */
+
+/**
+ * g_weak_ref_init: (skip)
+ * @weak_ref: (inout): uninitialized or empty location for a weak
+ * reference
+ * @object: (allow-none): a #GObject or %NULL
+ *
+ * Initialise a non-statically-allocated #GWeakRef.
+ *
+ * This function also calls g_weak_ref_set() with @object on the
+ * freshly-initialised weak reference.
+ *
+ * This function should always be matched with a call to
+ * g_weak_ref_clear(). It is not necessary to use this function for a
+ * #GWeakRef in static storage because it will already be
+ * properly initialised. Just use g_weak_ref_set() directly.
+ *
+ * Since: 2.32
+ */
+void
+g_weak_ref_init (GWeakRef *weak_ref,
+ gpointer object)
+{
+ weak_ref->priv.p = NULL;
+
+ g_weak_ref_set (weak_ref, object);
+}
+
+/**
+ * g_weak_ref_clear: (skip)
+ * @weak_ref: (inout): location of a weak reference, which
+ * may be empty
+ *
+ * Frees resources associated with a non-statically-allocated #GWeakRef.
+ * After this call, the #GWeakRef is left in an undefined state.
+ *
+ * You should only call this on a #GWeakRef that previously had
+ * g_weak_ref_init() called on it.
+ *
+ * Since: 2.32
+ */
+void
+g_weak_ref_clear (GWeakRef *weak_ref)
+{
+ g_weak_ref_set (weak_ref, NULL);
+
+ /* be unkind */
+ weak_ref->priv.p = (void *) 0xccccccccu;
+}
+
+/**
+ * g_weak_ref_get: (skip)
+ * @weak_ref: (inout): location of a weak reference to a #GObject
+ *
+ * If @weak_ref is not empty, atomically acquire a strong
+ * reference to the object it points to, and return that reference.
+ *
+ * This function is needed because of the potential race between taking
+ * the pointer value and g_object_ref() on it, if the object was losing
+ * its last reference at the same time in a different thread.
+ *
+ * The caller should release the resulting reference in the usual way,
+ * by using g_object_unref().
+ *
+ * Returns: (transfer full) (type GObject.Object): the object pointed to
+ * by @weak_ref, or %NULL if it was empty
+ *
+ * Since: 2.32
+ */
+gpointer
+g_weak_ref_get (GWeakRef *weak_ref)
+{
+ gpointer object_or_null;
+
+ g_return_val_if_fail (weak_ref!= NULL, NULL);
+
+ g_rw_lock_reader_lock (&weak_locations_lock);
+
+ object_or_null = weak_ref->priv.p;
+
+ if (object_or_null != NULL)
+ g_object_ref (object_or_null);
+
+ g_rw_lock_reader_unlock (&weak_locations_lock);
+
+ return object_or_null;
+}
+
+/**
+ * g_weak_ref_set: (skip)
+ * @weak_ref: location for a weak reference
+ * @object: (allow-none): a #GObject or %NULL
+ *
+ * Change the object to which @weak_ref points, or set it to
+ * %NULL.
+ *
+ * You must own a strong reference on @object while calling this
+ * function.
+ *
+ * Since: 2.32
+ */
+void
+g_weak_ref_set (GWeakRef *weak_ref,
+ gpointer object)
+{
+ GSList **weak_locations;
+ GObject *new_object;
+ GObject *old_object;
+
+ g_return_if_fail (weak_ref != NULL);
+ g_return_if_fail (object == NULL || G_IS_OBJECT (object));
+
+ new_object = object;
+
+ g_rw_lock_writer_lock (&weak_locations_lock);
+
+ /* We use the extra level of indirection here so that if we have ever
+ * had a weak pointer installed at any point in time on this object,
+ * we can see that there is a non-NULL value associated with the
+ * weak-pointer quark and know that this value will not change at any
+ * point in the object's lifetime.
+ *
+ * Both properties are important for reducing the amount of times we
+ * need to acquire locks and for decreasing the duration of time the
+ * lock is held while avoiding some rather tricky races.
+ *
+ * Specifically: we can avoid having to do an extra unconditional lock
+ * in g_object_unref() without worrying about some extremely tricky
+ * races.
+ */
+
+ old_object = weak_ref->priv.p;
+ if (new_object != old_object)
+ {
+ weak_ref->priv.p = new_object;
+
+ /* Remove the weak ref from the old object */
+ if (old_object != NULL)
+ {
+ weak_locations = g_datalist_id_get_data (&old_object->qdata, quark_weak_locations);
+ /* for it to point to an object, the object must have had it added once */
+ g_assert (weak_locations != NULL);
+
+ *weak_locations = g_slist_remove (*weak_locations, weak_ref);
+ }
+
+ /* Add the weak ref to the new object */
+ if (new_object != NULL)
+ {
+ weak_locations = g_datalist_id_get_data (&new_object->qdata, quark_weak_locations);
+
+ if (weak_locations == NULL)
+ {
+ weak_locations = g_new0 (GSList *, 1);
+ g_datalist_id_set_data_full (&new_object->qdata, quark_weak_locations, weak_locations, g_free);
+ }
+
+ *weak_locations = g_slist_prepend (*weak_locations, weak_ref);
+ }
+ }
+
+ g_rw_lock_writer_unlock (&weak_locations_lock);
+}