mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 11:11:08 +00:00
gstpad: Make calls to GstPadActivateFunction MT-safe
checking whether we already were in the target GstPadMode was being done too early and there was the risk that we *would* end up (de)activating a pad more than once. Instead, re-do the check for pad mode when entering the final pad (de)activation block. https://bugzilla.gnome.org/show_bug.cgi?id=790431
This commit is contained in:
parent
7595c38a73
commit
80262013ca
1 changed files with 28 additions and 10 deletions
38
gst/gstpad.c
38
gst/gstpad.c
|
@ -959,12 +959,19 @@ gst_pad_mode_get_name (GstPadMode mode)
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* Returns TRUE if pad wasn't already in the new_mode */
|
||||||
|
static gboolean
|
||||||
pre_activate (GstPad * pad, GstPadMode new_mode)
|
pre_activate (GstPad * pad, GstPadMode new_mode)
|
||||||
{
|
{
|
||||||
switch (new_mode) {
|
switch (new_mode) {
|
||||||
case GST_PAD_MODE_NONE:
|
case GST_PAD_MODE_NONE:
|
||||||
GST_OBJECT_LOCK (pad);
|
GST_OBJECT_LOCK (pad);
|
||||||
|
if (new_mode == GST_PAD_MODE (pad)) {
|
||||||
|
GST_WARNING_OBJECT (pad,
|
||||||
|
"Pad is already in the process of being deactivated");
|
||||||
|
GST_OBJECT_UNLOCK (pad);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
GST_DEBUG_OBJECT (pad, "setting PAD_MODE NONE, set flushing");
|
GST_DEBUG_OBJECT (pad, "setting PAD_MODE NONE, set flushing");
|
||||||
GST_PAD_SET_FLUSHING (pad);
|
GST_PAD_SET_FLUSHING (pad);
|
||||||
pad->ABI.abi.last_flowret = GST_FLOW_FLUSHING;
|
pad->ABI.abi.last_flowret = GST_FLOW_FLUSHING;
|
||||||
|
@ -976,6 +983,12 @@ pre_activate (GstPad * pad, GstPadMode new_mode)
|
||||||
case GST_PAD_MODE_PUSH:
|
case GST_PAD_MODE_PUSH:
|
||||||
case GST_PAD_MODE_PULL:
|
case GST_PAD_MODE_PULL:
|
||||||
GST_OBJECT_LOCK (pad);
|
GST_OBJECT_LOCK (pad);
|
||||||
|
if (new_mode == GST_PAD_MODE (pad)) {
|
||||||
|
GST_WARNING_OBJECT (pad,
|
||||||
|
"Pad is already in the process of being activated");
|
||||||
|
GST_OBJECT_UNLOCK (pad);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
GST_DEBUG_OBJECT (pad, "setting pad into %s mode, unset flushing",
|
GST_DEBUG_OBJECT (pad, "setting pad into %s mode, unset flushing",
|
||||||
gst_pad_mode_get_name (new_mode));
|
gst_pad_mode_get_name (new_mode));
|
||||||
GST_PAD_UNSET_FLUSHING (pad);
|
GST_PAD_UNSET_FLUSHING (pad);
|
||||||
|
@ -1004,6 +1017,7 @@ pre_activate (GstPad * pad, GstPadMode new_mode)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1173,18 +1187,22 @@ activate_mode_internal (GstPad * pad, GstObject * parent, GstPadMode mode,
|
||||||
/* Mark pad as needing reconfiguration */
|
/* Mark pad as needing reconfiguration */
|
||||||
if (active)
|
if (active)
|
||||||
GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_NEED_RECONFIGURE);
|
GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_NEED_RECONFIGURE);
|
||||||
pre_activate (pad, new);
|
|
||||||
|
|
||||||
if (GST_PAD_ACTIVATEMODEFUNC (pad)) {
|
/* pre_activate returns TRUE if we weren't already in the process of
|
||||||
if (G_UNLIKELY (!GST_PAD_ACTIVATEMODEFUNC (pad) (pad, parent, mode,
|
* switching to the 'new' mode */
|
||||||
active)))
|
if (pre_activate (pad, new)) {
|
||||||
goto failure;
|
|
||||||
} else {
|
if (GST_PAD_ACTIVATEMODEFUNC (pad)) {
|
||||||
/* can happen for sinks of passthrough elements */
|
if (G_UNLIKELY (!GST_PAD_ACTIVATEMODEFUNC (pad) (pad, parent, mode,
|
||||||
|
active)))
|
||||||
|
goto failure;
|
||||||
|
} else {
|
||||||
|
/* can happen for sinks of passthrough elements */
|
||||||
|
}
|
||||||
|
|
||||||
|
post_activate (pad, new);
|
||||||
}
|
}
|
||||||
|
|
||||||
post_activate (pad, new);
|
|
||||||
|
|
||||||
GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "%s in %s mode",
|
GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "%s in %s mode",
|
||||||
active ? "activated" : "deactivated", gst_pad_mode_get_name (mode));
|
active ? "activated" : "deactivated", gst_pad_mode_get_name (mode));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue