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 685555 - collectpads unit test fails
collectpads unit test fails
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
git master
Other Linux
: Normal critical
: 1.1.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2012-10-05 12:13 UTC by Wim Taymans
Modified: 2013-03-18 10:53 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Call _pop() from collected callback to avoid races (5.79 KB, patch)
2013-03-07 11:19 UTC, Jonas Holmberg
committed Details | Review

Description Wim Taymans 2012-10-05 12:13:02 UTC
Doing make libs/collectpads.forever hangs after a while. From a quick look at the code it looks like collectpads has some races that cause it to lock up. The evt_cookie, for example, can be incremented before the other thread picks up the value and goes into an infinite wait.
Comment 1 Tim-Philipp Müller 2012-10-06 11:29:32 UTC
libs/collectpads.c:94:E:general:test_collect:0: (after this point) Test timeout expired
Comment 2 Jonas Holmberg 2013-03-07 11:19:12 UTC
Created attachment 238278 [details] [review]
Call _pop() from collected callback to avoid races
Comment 3 Jonas Holmberg 2013-03-07 13:20:13 UTC
There were three threads in the test cases that hanged: the test thread and two threads that push buffers. Each thread push one buffer on one pad. There are two pads in the collectpads so the second buffer will trigger the collect-callback. 

This is what happens when the hang occurs:

The first thread pushes a buffer and initializes a cookie to the value of a counter in the collectpads object and waits on a cond for the counter to change and for someone to consume the buffer (i.e. _pop() it).

The second thread pushes a buffer and calls the collected callback, which signals the cond that the test thread is waiting for.

The test thread pops both buffers (without holding any lock). Each call to _pop() increases the counter broadcasts the condition that the first thread is now waiting for. It then joins both threads (hangs).

The first thread wakes up and returns, since its buffer has been consumed.

The second thread starts executing again. When the callback, called by the second thread, has returned it initializes a cookie to the value of a counter, which has already prematurely been increased by the test thread when it popped the buffers, and wait's on a cond for the counter to change and for someone to consume the buffer (i.e. _pop() it). Since the buffer has already been poped and the counter has already been increased it will be stuck forever.
Comment 4 Tim-Philipp Müller 2013-03-18 10:52:35 UTC
commit afbba8974ae54c591edd725842422fe5d51a0350
Author: Jonas Holmberg <jonashg@axis.com>
Date:   Thu Mar 7 12:11:30 2013 +0100

    tests: fix spurious failure in test_collect collectpads test
    
    pop() in collected callback.
    
    There were three threads in the test cases that hanged: the test thread and two
    threads that push buffers. Each thread push one buffer on one pad. There are
    two pads in the collectpads so the second buffer will trigger the
    collect-callback.
    
    This is what happens when the hang occurs:
    
    The first thread pushes a buffer and initializes a cookie to the value of a
    counter in the collectpads object and waits on a cond for the counter to change
    and for someone to consume the buffer (i.e. _pop() it).
    
    The second thread pushes a buffer and calls the collected callback, which
    signals the cond that the test thread is waiting for.
    
    The test thread pops both buffers (without holding any lock). Each call to
    _pop() increases the counter broadcasts the condition that the first thread is
    now waiting for. It then joins both threads (hangs).
    
    The first thread wakes up and returns, since its buffer has been consumed.
    
    The second thread starts executing again. When the callback, called by the
    second thread, has returned it initializes a cookie to the value of a counter,
    which has already prematurely been increased by the test thread when it popped
    the buffers, and wait's on a cond for the counter to change and for someone to
    consume the buffer (i.e. _pop() it). Since the buffer has already been poped
    and the counter has already been increased it will be stuck forever.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=685555