After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 510354 - post GST_MESSAGE_STRUCTURE_CHANGE when linking and unlinking pads
post GST_MESSAGE_STRUCTURE_CHANGE when linking and unlinking pads
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
git master
Other Linux
: Normal normal
: 0.10.22
Assigned To: GStreamer Maintainers
GStreamer Maintainers
: 544440 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2008-01-18 10:24 UTC by Alessandro Decina
Modified: 2008-10-06 16:16 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Test case and patch (12.82 KB, patch)
2008-01-18 10:25 UTC, Alessandro Decina
needs-work Details | Review
Updated patch. (13.50 KB, patch)
2008-01-24 23:30 UTC, Ole André Vadla Ravnås
none Details | Review
More aggressive test casee (1.58 KB, text/plain)
2008-07-23 21:06 UTC, Olivier Crête
  Details
Further updated patch (17.74 KB, patch)
2008-07-25 00:33 UTC, Olivier Crête
none Details | Review
Possibly complete patch? (15.74 KB, patch)
2008-08-21 00:43 UTC, Olivier Crête
none Details | Review
updated again (15.78 KB, patch)
2008-08-23 00:08 UTC, Olivier Crête
none Details | Review
updated again (15.78 KB, patch)
2008-08-23 00:08 UTC, Olivier Crête
committed Details | Review

Description Alessandro Decina 2008-01-18 10:24:28 UTC
The patch posts GST_MESSAGE_STRUCTURE_CHANGE when pads are linked or unlinked. The message is handled by GstBin to make GstBinSortIterator resync when linking or unlinking happens.
Comment 1 Alessandro Decina 2008-01-18 10:25:06 UTC
Created attachment 103130 [details] [review]
Test case and patch
Comment 2 Wim Taymans 2008-01-18 14:09:17 UTC
yeps, perfect.
Comment 3 Wim Taymans 2008-01-23 15:34:47 UTC
the patch is not working, the pad is linked before the message is posted so that the bin could still end up doing the wrong thing. Perhaps a start/stop message sequence would help.
Comment 4 Ole André Vadla Ravnås 2008-01-24 23:30:39 UTC
Created attachment 103689 [details] [review]
Updated patch.

I ran into the issue described by this bug and tried the original patch, but still hit the same issue. After debugging I came to the conclusion
described by Wim.

This patch builds on the original patch but uses a start/stop sequence
before/after the changes are made. I was able to reproduce the race quite
reliably in less than 20 full-duplex a/v calls with rtpmanager before this patch
(all inside one process using the loopback interface, so things get quite racy).
Have not yet been able to reproduce with 100 call-setups. Will keep pounding and
report back if I hit it again.

Would it be preferable to have GST_MESSAGE_STRUCTURE_CHANGE_{START,DONE} instead
of one message for both by the way? (To follow the same pattern as the other messages that are sequenced.)
Or alternatively something shorter like GST_MESSAGE_RESTRUCTURE_{START,DONE}, which as an added bonus means not having to re-indent all the other entries' equal-signs and make for a huge diff. :)
Comment 5 Wim Taymans 2008-01-28 16:39:58 UTC
I'm not very comfortable with a message taking an object lock and another message releasing it again. 

What about making the parent ignore the link to a pad that posted the STRUCTURE_CHANGE start message and making it restart the state change when the stop message incremented the counter? This would not require any permanent locks.
Comment 6 Olivier Crête 2008-07-23 21:04:16 UTC
*** Bug 544440 has been marked as a duplicate of this bug. ***
Comment 7 Olivier Crête 2008-07-23 21:06:10 UTC
Created attachment 115124 [details]
More aggressive test casee

I'm adding a much more aggressive test case..
Comment 8 Olivier Crête 2008-07-24 22:26:33 UTC
Looking at the code, I guess the GstBin has to keep a list of pads in transition. But I'm afraid its not that simple, since the element that has the pad could be removed from the bin in the mean time. So maybe instead the element should listen to the "linked" and "unlinked" signals and emit the messages (and also emit the done message on the bin when the parent is changed.. if thats even doable...)
Comment 9 Olivier Crête 2008-07-24 22:34:35 UTC
Actually, I'm stupid. The bin knows when elements are removed... so I guess it can remove the element/pads from the in-transition list when they are removed.
Comment 10 Olivier Crête 2008-07-24 22:52:03 UTC
Also, the patch seems to look directly at the parent field of the gstobject without taking the object lock
Comment 11 Olivier Crête 2008-07-24 23:35:25 UTC
I guess removing an element from a bin will first unlink all pads that are still linked, so its a non-issue?
Comment 12 Olivier Crête 2008-07-25 00:33:16 UTC
Created attachment 115214 [details] [review]
Further updated patch

I'm adding that patch that adds a GPtrArray of the currently changing pads to GstBin and checks if the pads in there in the iterator update_degree function.

I see only one problem with the current patch, the update_degree() function seems to be sometimes called with the GstBin lock held (on lock creation) and sometimes without (other times). So we can't do locking properly inside there, maybe there should be another lock just for that list ?
Comment 13 Olivier Crête 2008-08-21 00:43:49 UTC
Created attachment 117098 [details] [review]
Possibly complete patch?

I've changed the patch to use the bin->messages to store messages. I also changed it to update the structure_cookie at the start and at the end of the structure change (otherwise it still failed in some cases).
Comment 14 Olivier Crête 2008-08-23 00:08:33 UTC
Created attachment 117247 [details] [review]
updated again

oops, the last patch had one case where it could try to unref a NULL..
Comment 15 Olivier Crête 2008-08-23 00:08:37 UTC
Created attachment 117248 [details] [review]
updated again

oops, the last patch had one case where it could try to unref a NULL..
Comment 16 Wim Taymans 2008-09-26 08:59:39 UTC
Last patch starts to look good to me. 

There is one last thing, when we remove the element from the bin we would need to remove all the pads that still have pending messages of this element. While the pad always posts both start/done message pairs, it's possible that the element is removed from the bin before the done message is posted, leaing the start message in the bin still. It'll cause a leak because the pad cannot be finalized because the message has a ref to it.

I would propose to add the element to the message structure for this purpose.

Update to patch welcome or wait till I take a look at this after the freeze.
Comment 17 Wim Taymans 2008-10-06 16:16:09 UTC
Commited with some updates.

        Based on Patch by: Olivier Crete <tester at tester dot ca>

        * gst/gstbin.c: (gst_bin_init), (gst_bin_add_func),
        (gst_bin_remove_func), (update_degree),
        (gst_bin_sort_iterator_new), (gst_bin_handle_message_func):
        Keep track of pads that are being linked/unlinked and resync the state
        changes.

        * gst/gstpad.c: (gst_pad_get_direction),
        (gst_pad_set_chain_function), (gst_pad_set_getrange_function),
        (gst_pad_set_checkgetrange_function), (gst_pad_unlink),
        (gst_pad_link_prepare), (gst_pad_link),
        (gst_pad_event_default_dispatch), (gst_pad_chain), (gst_pad_push),
        (gst_pad_check_pull_range), (gst_pad_get_range),
        (gst_pad_pull_range):
        Some code cleanups, use macros to check pad direction.
        Don't need to take the lock on the pad direction.
        Post structure change when pads are linked/unlinked.
        Change some checks into _return_if_fail().

        * tests/check/gst/gstbin.c:
        (test_link_structure_change_state_changed_sync_cb),
        (GST_START_TEST), (gst_bin_suite):
        Add testcase for pad link/unlinke resync during a state change.
        Fixes #510354.

        * docs/gst/gstreamer-sections.txt:
        * gst/gstmessage.c: (gst_message_new_structure_change),
        (gst_message_parse_structure_change):
        * gst/gstmessage.h:
        Implement STRUCTURE_CHANGED messages. These messages will be used to
        signal the parent bin of link/unlink operations that could require a
        resync when doing a state change. See ##510354.
        API: gst_message_new_structure_change()
        API: gst_message_parse_structure_change()

        * gst/gstquark.c:
        * gst/gstquark.h:
        Add some more quarks for new message. See #510354.