[gstreamer-bugs] [Bug 635785] basesrc: fix deadlock

GStreamer (bugzilla.gnome.org) bugzilla at gnome.org
Thu Nov 25 08:25:36 PST 2010


https://bugzilla.gnome.org/show_bug.cgi?id=635785
  GStreamer | gstreamer (core) | unspecified

--- Comment #1 from Håvard Graff (hgr) <havard.graff at tandberg.com> 2010-11-25 16:25:32 UTC ---
More details:

<hgr> baseaudiosrc... 
<hgr> setting it between PLAYING and PAUSED really quickly, lots of times... 
<hgr> you get the following chain of events: 
<hgr> 1. PAUSED -> gst_base_src_wait_playing() is waiting in GST_LIVE_WAIT 
<hgr> 2. PLAYING -> gst_base_src_set_playing(live_play=TRUE) and the LIVE_LOCK
is taken 
<hgr> 3. the GST_LIVE_SIGNAL is signaled also inside gst_base_src_set_playing 
<hgr> 4. GST_LIVE_UNLOCK 
<hgr> Now the normal 5. would be that gst_base_src_wait_playing would
continue...after set_playing had let go of the lock... 
<hgr> however, very race, now 5. is PAUSED->
gst_base_src_set_playing(live_play=FALSE) and the LIVE_LOCK is taken *before*
the g_cond can take it again... 
<hgr> so then we get 6. GST_LIVE_UNLOCK inside gst_base_src_set_playing 
<hgr> and then 
<hgr> 7. gst_base_src_wait_playing continues 
<hgr> however, this ends up inside a 8. gst_ring_buffer_read () 
<wtay> oh 
<wtay> missing while around g_cond_wait() ? 
<hgr> and unless there is any buffer inside this read, it will block on
GST_RING_BUFFER_WAIT() 
<hgr> and now the state-change goes to PLAYING again... 
<hgr> and then noone will signal GST_RINGBUFFER_SIGNAL (that only happends when
going to PAUSED) 
<hgr> so you get a deadlock, where the state-changeing thread blocks on
gst_base_src_set_playing(live_play=TRUE) on the LIVE_LOCK, that is held by the
basesrc-thread, waiting for GST_RINGBUFFER_SIGNAL 
<hgr> the good news is that this only happens about every 1,5 million
state-changes, the bad news is that it *can* happen, and hence should be
fixed... :) 
<wtay> gst_base_src_wait_playing() is inside a loop that can only exit when
live_running = TRUE 
<wtay> or maybe audiosrc does something special... 
<hgr> however, it would probably not fix this issue, because
gst_base_src_set_playing needs to know that wait_playing has stopped waiting
before it is safe to return 
<wtay> indeed 
<wtay> the audio base class doesn't have a while loop 
<wtay> bad 
<hgr> ah, yeah, I know what while-loop you meant now... the one inside
gst_base_src... ! I am talking about audiobasesrc 
<wtay> it needs a while loop. either move it around in basesrc or add to
audiosrc 
<wtay> just move the while loop in wait-playing 
<wtay> it actually makes the method do what its name says :) 
<hgr> I guess... so you would keep waiting if it is not yet running? 
<wtay> yes 
<wtay> like in the get_range function 
<hgr> exactly 
<hgr> I'll try it :) 
<wtay> great 
<hgr> it looks perfect! I have never been able to run for this long before...
(*10) 
<wtay> yay 
<wtay> it makes sense, though 
<hgr> yup 
<hgr> I'll submit the patch asap 
<wtay> after a gcond, you always have to recheck the conditions that made you
go into the gcond 
<wtay> ..always.. 
<hgr> I now have *100 better than my best run 
<hgr> I say no more deadlock 
<wtay> easy fix

-- 
Configure bugmail: https://bugzilla.gnome.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.



More information about the Gstreamer-bugs mailing list