gststructure: Fix gst_structure_take ownership handling
authorJan Alexander Steffens (heftig) <jsteffens@make.tv>
Mon, 23 Mar 2020 11:28:12 +0000 (12:28 +0100)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Mon, 23 Mar 2020 16:48:47 +0000 (16:48 +0000)
commita20ff6aaf48a09f46a1e63147ca080f6904e607a
treeb306f7acc43f99d522be1d6a11fd9d46778384ae
parente45f187d1386e95cbb92d5090a21f8acd5ff942b
gststructure: Fix gst_structure_take ownership handling

The old code would leave a dangling pointer in oldstr_ptr if two threads
attempted to take the same structure into the same location at the same
time:

1. First "oldstr == newstr" check (before the loop) fails.
2. Compare-and-exchange fails, due to a second thread completing the
   same gst_structure_take.
3. Second "oldstr == newstr" check (in the loop) succeeds, loop breaks.
4. "oldstr" check succeeds, old structure gets freed.
5. oldstr_ptr now contains a dangling pointer.

This shouldn't happen in code that handles ownership sanely, so check
that we don't try to do this and complain loudly.

Also simplify the function by using a do-while loop, like
gst_mini_object_take.

https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/413
gst/gststructure.c