+ G_LOCK (qdata_mutex);
+ if ((i = find_notify (object, weak_ref_quark, TRUE, notify, data)) != -1) {
+ remove_notify (object, i);
+ } else {
+ g_warning ("%s: couldn't find weak ref %p (object:%p data:%p)", G_STRFUNC,
+ notify, object, data);
+ }
+ G_UNLOCK (qdata_mutex);
+}
+
+/**
+ * gst_mini_object_set_qdata:
+ * @object: a #GstMiniObject
+ * @quark: A #GQuark, naming the user data pointer
+ * @data: An opaque user data pointer
+ * @destroy: Function to invoke with @data as argument, when @data
+ * needs to be freed
+ *
+ * This sets an opaque, named pointer on a miniobject.
+ * The name is specified through a #GQuark (retrieved e.g. via
+ * g_quark_from_static_string()), and the pointer
+ * can be gotten back from the @object with gst_mini_object_get_qdata()
+ * until the @object is disposed.
+ * Setting a previously set user data pointer, overrides (frees)
+ * the old pointer set, using %NULL as pointer essentially
+ * removes the data stored.
+ *
+ * @destroy may be specified which is called with @data as argument
+ * when the @object is disposed, or the data is being overwritten by
+ * a call to gst_mini_object_set_qdata() with the same @quark.
+ */
+void
+gst_mini_object_set_qdata (GstMiniObject * object, GQuark quark,
+ gpointer data, GDestroyNotify destroy)
+{
+ gint i;
+ gpointer old_data = NULL;
+ GDestroyNotify old_notify = NULL;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (quark > 0);
+
+ G_LOCK (qdata_mutex);
+ if ((i = find_notify (object, quark, FALSE, NULL, NULL)) != -1) {
+ PrivData *priv_data = object->priv_pointer;
+
+ old_data = QDATA_DATA (priv_data, i);
+ old_notify = QDATA_DESTROY (priv_data, i);
+
+ if (data == NULL)
+ remove_notify (object, i);
+ }
+ if (data != NULL)
+ set_notify (object, i, quark, NULL, data, destroy);
+ G_UNLOCK (qdata_mutex);
+
+ if (old_notify)
+ old_notify (old_data);
+}
+
+/**
+ * gst_mini_object_get_qdata:
+ * @object: The GstMiniObject to get a stored user data pointer from
+ * @quark: A #GQuark, naming the user data pointer
+ *
+ * This function gets back user data pointers stored via
+ * gst_mini_object_set_qdata().
+ *
+ * Returns: (transfer none) (nullable): The user data pointer set, or
+ * %NULL
+ */
+gpointer
+gst_mini_object_get_qdata (GstMiniObject * object, GQuark quark)
+{
+ guint i;
+ gpointer result;
+
+ g_return_val_if_fail (object != NULL, NULL);
+ g_return_val_if_fail (quark > 0, NULL);
+
+ G_LOCK (qdata_mutex);
+ if ((i = find_notify (object, quark, FALSE, NULL, NULL)) != -1) {
+ PrivData *priv_data = object->priv_pointer;
+ result = QDATA_DATA (priv_data, i);
+ } else {
+ result = NULL;
+ }
+ G_UNLOCK (qdata_mutex);
+
+ return result;
+}
+
+/**
+ * gst_mini_object_steal_qdata:
+ * @object: The GstMiniObject to get a stored user data pointer from
+ * @quark: A #GQuark, naming the user data pointer
+ *
+ * This function gets back user data pointers stored via gst_mini_object_set_qdata()
+ * and removes the data from @object without invoking its destroy() function (if
+ * any was set).
+ *
+ * Returns: (transfer full) (nullable): The user data pointer set, or
+ * %NULL
+ */
+gpointer
+gst_mini_object_steal_qdata (GstMiniObject * object, GQuark quark)
+{
+ guint i;
+ gpointer result;
+
+ g_return_val_if_fail (object != NULL, NULL);
+ g_return_val_if_fail (quark > 0, NULL);
+
+ G_LOCK (qdata_mutex);
+ if ((i = find_notify (object, quark, FALSE, NULL, NULL)) != -1) {
+ PrivData *priv_data = object->priv_pointer;
+ result = QDATA_DATA (priv_data, i);
+ remove_notify (object, i);
+ } else {
+ result = NULL;
+ }
+ G_UNLOCK (qdata_mutex);
+
+ return result;
+}
+
+/**
+ * gst_mini_object_add_parent:
+ * @object: a #GstMiniObject
+ * @parent: a parent #GstMiniObject
+ *
+ * This adds @parent as a parent for @object. Having one ore more parents affects the
+ * writability of @object: if a @parent is not writable, @object is also not
+ * writable, regardless of its refcount. @object is only writable if all
+ * the parents are writable and its own refcount is exactly 1.
+ *
+ * Note: This function does not take ownership of @parent and also does not
+ * take an additional reference. It is the responsibility of the caller to
+ * remove the parent again at a later time.
+ *
+ * Since: 1.16
+ */
+void
+gst_mini_object_add_parent (GstMiniObject * object, GstMiniObject * parent)
+{
+ gint priv_state;
+
+ g_return_if_fail (object != NULL);
+
+ GST_CAT_TRACE (GST_CAT_REFCOUNTING, "adding parent %p to object %p", parent,
+ object);