diff --git a/gst/gstpad.c b/gst/gstpad.c index 60f1d6e918..04c285e46c 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -1836,11 +1836,23 @@ gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad) goto not_linked_together; if (GST_PAD_UNLINKFUNC (srcpad)) { - GST_PAD_UNLINKFUNC (srcpad) (srcpad); + GstObject *tmpparent; + + ACQUIRE_PARENT (srcpad, tmpparent, no_src_parent); + + GST_PAD_UNLINKFUNC (srcpad) (srcpad, tmpparent); + RELEASE_PARENT (parent); } +no_src_parent: if (GST_PAD_UNLINKFUNC (sinkpad)) { - GST_PAD_UNLINKFUNC (sinkpad) (sinkpad); + GstObject *tmpparent; + + ACQUIRE_PARENT (sinkpad, tmpparent, no_sink_parent); + + GST_PAD_UNLINKFUNC (sinkpad) (sinkpad, tmpparent); + RELEASE_PARENT (parent); } +no_sink_parent: /* first clear peers */ GST_PAD_PEER (srcpad) = NULL; @@ -2210,13 +2222,22 @@ gst_pad_link_full (GstPad * srcpad, GstPad * sinkpad, GstPadLinkCheck flags) GST_OBJECT_UNLOCK (srcpad); if (srcfunc) { + GstObject *tmpparent; + + ACQUIRE_PARENT (srcpad, tmpparent, no_parent); /* this one will call the peer link function */ - result = srcfunc (srcpad, sinkpad); + result = srcfunc (srcpad, tmpparent, sinkpad); + RELEASE_PARENT (tmpparent); } else if (sinkfunc) { + GstObject *tmpparent; + + ACQUIRE_PARENT (sinkpad, tmpparent, no_parent); /* if no source link function, we need to call the sink link * function ourselves. */ - result = sinkfunc (sinkpad, srcpad); + result = sinkfunc (sinkpad, tmpparent, srcpad); + RELEASE_PARENT (tmpparent); } + no_parent: GST_OBJECT_LOCK (srcpad); GST_OBJECT_LOCK (sinkpad); diff --git a/gst/gstpad.h b/gst/gstpad.h index f14e7fe403..c6ac927359 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -396,20 +396,26 @@ typedef gboolean (*GstPadQueryFunction) (GstPad *pad, GstObject *parent, /** * GstPadLinkFunction: * @pad: the #GstPad that is linked. + * @parent: the parent of @pad. If the #GST_PAD_FLAG_NEED_PARENT flag is set, + * @parent is guaranteed to be not-NULL and remain valid during the + * execution of this function. * @peer: the peer #GstPad of the link * * Function signature to handle a new link on the pad. * * Returns: the result of the link with the specified peer. */ -typedef GstPadLinkReturn (*GstPadLinkFunction) (GstPad *pad, GstPad *peer); +typedef GstPadLinkReturn (*GstPadLinkFunction) (GstPad *pad, GstObject *parent, GstPad *peer); /** * GstPadUnlinkFunction: * @pad: the #GstPad that is linked. + * @parent: the parent of @pad. If the #GST_PAD_FLAG_NEED_PARENT flag is set, + * @parent is guaranteed to be not-NULL and remain valid during the + * execution of this function. * * Function signature to handle a unlinking the pad prom its peer. */ -typedef void (*GstPadUnlinkFunction) (GstPad *pad); +typedef void (*GstPadUnlinkFunction) (GstPad *pad, GstObject *parent); /* misc */ diff --git a/tests/check/gst/gstghostpad.c b/tests/check/gst/gstghostpad.c index af3c0af6e9..c93cc20882 100644 --- a/tests/check/gst/gstghostpad.c +++ b/tests/check/gst/gstghostpad.c @@ -802,7 +802,7 @@ static gint linked_count2; static gint unlinked_count2; static GstPadLinkReturn -pad_linked1 (GstPad * pad, GstPad * peer) +pad_linked1 (GstPad * pad, GstObject * parent, GstPad * peer) { linked_count1++; @@ -810,13 +810,13 @@ pad_linked1 (GstPad * pad, GstPad * peer) } static void -pad_unlinked1 (GstPad * pad) +pad_unlinked1 (GstPad * pad, GstObject * parent) { unlinked_count1++; } static GstPadLinkReturn -pad_linked2 (GstPad * pad, GstPad * peer) +pad_linked2 (GstPad * pad, GstObject * parent, GstPad * peer) { linked_count2++; @@ -824,7 +824,7 @@ pad_linked2 (GstPad * pad, GstPad * peer) } static void -pad_unlinked2 (GstPad * pad) +pad_unlinked2 (GstPad * pad, GstObject * parent) { unlinked_count2++; }