diff --git a/subprojects/gstreamer/gst/gstobject.h b/subprojects/gstreamer/gst/gstobject.h index 85e827533b..a7daf48e4e 100644 --- a/subprojects/gstreamer/gst/gstobject.h +++ b/subprojects/gstreamer/gst/gstobject.h @@ -88,6 +88,34 @@ typedef enum * It blocks until the lock can be obtained. */ #define GST_OBJECT_LOCK(obj) g_mutex_lock(GST_OBJECT_GET_LOCK(obj)) + +/** + * GST_OBJECT_AUTO_LOCK: + * @obj: a #GstObject to lock + * @var: a variable name to be declared + * + * Declare a #GMutexLocker variable with g_autoptr() and lock the object. The + * mutex will be unlocked automatically when leaving the scope. + * + * ``` c + * { + * GST_OBJECT_AUTO_LOCK (obj, locker); + * + * obj->stuff_with_lock(); + * if (cond) { + * // No need to unlock + * return; + * } + * + * // Unlock before end of scope + * g_clear_pointer (&locker, g_mutex_locker_free); + * obj->stuff_without_lock(); + * } + * ``` + * Since: 1.24.0 + */ +#define GST_OBJECT_AUTO_LOCK(obj, var) g_autoptr(GMutexLocker) G_GNUC_UNUSED var = g_mutex_locker_new(GST_OBJECT_GET_LOCK(obj)) + /** * GST_OBJECT_TRYLOCK: * @obj: a #GstObject. diff --git a/subprojects/gstreamer/gst/gstpad.h b/subprojects/gstreamer/gst/gstpad.h index c89be30508..86f2af1611 100644 --- a/subprojects/gstreamer/gst/gstpad.h +++ b/subprojects/gstreamer/gst/gstpad.h @@ -1249,6 +1249,34 @@ struct _GstPadClass { * when buffers or serialized downstream events are pushed on a pad. */ #define GST_PAD_STREAM_LOCK(pad) g_rec_mutex_lock(GST_PAD_GET_STREAM_LOCK(pad)) + +/** + * GST_PAD_STREAM_AUTO_LOCK + * @pad: a #GstPad + * @var: a variable name to be declared + * + * Declare a #GRecMutexLocker variable with g_autoptr() and lock the pad. The + * recursive mutex will be unlocked automatically when leaving the scope. + * + * ``` c + * { + * GST_PAD_STREAM_AUTO_LOCK (pad, locker); + * + * gst_pad_push_event(pad, event1); + * if (cond) { + * // No need to unlock + * return; + * } + * + * // Unlock before end of scope + * g_clear_pointer (&locker, g_rec_mutex_locker_free); + * gst_pad_push_event(pad, event2); + * } + * ``` + * Since: 1.24.0 + */ +#define GST_PAD_STREAM_AUTO_LOCK(pad, var) g_autoptr(GRecMutexLocker) G_GNUC_UNUSED var = g_rec_mutex_locker_new(GST_PAD_GET_STREAM_LOCK(pad)) + /** * GST_PAD_STREAM_TRYLOCK: * @pad: a #GstPad diff --git a/subprojects/gstreamer/tests/check/gst/gstobject.c b/subprojects/gstreamer/tests/check/gst/gstobject.c index 3d9660a48c..9daee3a650 100644 --- a/subprojects/gstreamer/tests/check/gst/gstobject.c +++ b/subprojects/gstreamer/tests/check/gst/gstobject.c @@ -284,12 +284,18 @@ GST_START_TEST (test_fake_object_name_threaded_right) /* start looping and set/get name repeatedly */ for (i = 0; i < 1000; ++i) { +#ifndef g_autoptr GST_OBJECT_LOCK (object); +#else + GST_OBJECT_AUTO_LOCK (object, locker); +#endif g_free (GST_OBJECT_NAME (object)); GST_OBJECT_NAME (object) = g_strdup ("main"); THREAD_SWITCH (); name = g_strdup (GST_OBJECT_NAME (object)); +#ifndef g_autoptr GST_OBJECT_UNLOCK (object); +#endif fail_unless (strcmp (name, "main") == 0, "Name got changed while lock held during run %d", i);