+ * gst_mini_object_lock:
+ * @object: the mini-object to lock
+ * @flags: #GstLockFlags
+ *
+ * Lock the mini-object with the specified access mode in @flags.
+ *
+ * Returns: %TRUE if @object could be locked.
+ */
+gboolean
+gst_mini_object_lock (GstMiniObject * object, GstLockFlags flags)
+{
+ gint access_mode, state, newstate;
+
+ g_return_val_if_fail (object != NULL, FALSE);
+ g_return_val_if_fail (GST_MINI_OBJECT_IS_LOCKABLE (object), FALSE);
+
+ if (G_UNLIKELY (object->flags & GST_MINI_OBJECT_FLAG_LOCK_READONLY &&
+ flags & GST_LOCK_FLAG_WRITE))
+ return FALSE;
+
+ do {
+ access_mode = flags & FLAG_MASK;
+ newstate = state = g_atomic_int_get (&object->lockstate);
+
+ GST_CAT_TRACE (GST_CAT_LOCKING, "lock %p: state %08x, access_mode %d",
+ object, state, access_mode);
+
+ if (access_mode & GST_LOCK_FLAG_EXCLUSIVE) {
+ /* shared ref */
+ newstate += SHARE_ONE;
+ access_mode &= ~GST_LOCK_FLAG_EXCLUSIVE;
+ }
+
+ /* shared counter > 1 and write access is not allowed */
+ if (((state & GST_LOCK_FLAG_WRITE) != 0
+ || (access_mode & GST_LOCK_FLAG_WRITE) != 0)
+ && IS_SHARED (newstate))
+ goto lock_failed;
+
+ if (access_mode) {
+ if ((state & LOCK_FLAG_MASK) == 0) {
+ /* nothing mapped, set access_mode */
+ newstate |= access_mode;
+ } else {
+ /* access_mode must match */
+ if ((state & access_mode) != access_mode)
+ goto lock_failed;
+ }
+ /* increase refcount */
+ newstate += LOCK_ONE;
+ }
+ } while (!g_atomic_int_compare_and_exchange (&object->lockstate, state,
+ newstate));
+
+ return TRUE;
+
+lock_failed:
+ {
+ GST_CAT_DEBUG (GST_CAT_LOCKING,
+ "lock failed %p: state %08x, access_mode %d", object, state,
+ access_mode);
+ return FALSE;
+ }
+}
+
+/**
+ * gst_mini_object_unlock:
+ * @object: the mini-object to unlock
+ * @flags: #GstLockFlags
+ *
+ * Unlock the mini-object with the specified access mode in @flags.
+ */
+void
+gst_mini_object_unlock (GstMiniObject * object, GstLockFlags flags)
+{
+ gint access_mode, state, newstate;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GST_MINI_OBJECT_IS_LOCKABLE (object));
+
+ do {
+ access_mode = flags & FLAG_MASK;
+ newstate = state = g_atomic_int_get (&object->lockstate);
+
+ GST_CAT_TRACE (GST_CAT_LOCKING, "unlock %p: state %08x, access_mode %d",
+ object, state, access_mode);
+
+ if (access_mode & GST_LOCK_FLAG_EXCLUSIVE) {
+ /* shared counter */
+ g_return_if_fail (state >= SHARE_ONE);
+ newstate -= SHARE_ONE;
+ access_mode &= ~GST_LOCK_FLAG_EXCLUSIVE;
+ }
+
+ if (access_mode) {
+ g_return_if_fail ((state & access_mode) == access_mode);
+ /* decrease the refcount */
+ newstate -= LOCK_ONE;
+ /* last refcount, unset access_mode */
+ if ((newstate & LOCK_FLAG_MASK) == access_mode)
+ newstate &= ~LOCK_FLAG_MASK;
+ }
+ } while (!g_atomic_int_compare_and_exchange (&object->lockstate, state,
+ newstate));
+}
+
+/**