Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/GStreamer/gstreamer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Alexander Steffens (heftig) <jan.steffens@ltnglobal.com>2021-08-24 15:53:30 +0300
committerJan Alexander Steffens (heftig) <jan.steffens@ltnglobal.com>2021-08-24 16:13:19 +0300
commit148ac71a1fa8b698a8232b714f84419f51bda5ef (patch)
tree3003a81047a14039193bf535bfcbc0ba2753d846
parent637b0d8dc25b660d3b05370e60a95249a5228a39 (diff)
pad: Keep IDLE probe hook alive during immediate callback
When the probe returns GST_PAD_PROBE_REMOVE and gets called concurrently from the streaming thread while we're in the callback here, the hook has already been destroyed by the time we've reacquired the object lock. Consequently, cleanup_hook gets passed an invalid pointer. Keep another reference to the hook alive to avoid this situation. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/873>
-rw-r--r--gst/gstpad.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/gst/gstpad.c b/gst/gstpad.c
index 5197cd515c..bccba4ee08 100644
--- a/gst/gstpad.c
+++ b/gst/gstpad.c
@@ -1371,8 +1371,10 @@ cleanup_hook (GstPad * pad, GHook * hook)
GST_DEBUG_OBJECT (pad,
"cleaning up hook %lu with flags %08x", hook->hook_id, hook->flags);
- if (!G_HOOK_IS_VALID (hook))
+ if (!G_HOOK_IS_VALID (hook)) {
+ /* We've already destroyed this hook */
return;
+ }
type = (hook->flags) >> G_HOOK_FLAG_USER_SHIFT;
@@ -1492,6 +1494,9 @@ gst_pad_add_probe (GstPad * pad, GstPadProbeType mask,
gst_object_ref (pad);
pad->priv->idle_running++;
+ /* Ref the hook, it could be destroyed by the callback or concurrently */
+ g_hook_ref (&pad->probes, hook);
+
/* the pad is idle now, we can signal the idle callback now */
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"pad is idle, trigger idle callback");
@@ -1523,6 +1528,7 @@ gst_pad_add_probe (GstPad * pad, GstPadProbeType mask,
GST_DEBUG_OBJECT (pad, "probe returned %d", ret);
break;
}
+ g_hook_unref (&pad->probes, hook);
pad->priv->idle_running--;
if (pad->priv->idle_running == 0) {
GST_PAD_BLOCK_BROADCAST (pad);