rtpjitterbuffer: Waiting on timers during EOS handling can deadlock
This is related to !608 (merged) .
What happens is the following:
- The streaming thread waits on the timers
if (type == ITEM_TYPE_EVENT && outevent &&
GST_EVENT_TYPE (outevent) == GST_EVENT_EOS) {
g_assert (priv->eos);
while (rtp_timer_queue_length (priv->timers) > 0) {
/* Stopping timers */
unschedule_current_timer (jitterbuffer);
JBUF_WAIT_TIMER (priv);
}
}
-
gst_rtp_jitter_buffer_flush_start()
does not cause any flushing or anything of the timers. DoingJBUF_SIGNAL_TIMER
would not be sufficient (would still be racy) because nothing is making sure that the timers are actually flushed away. Maybe code similar to theGST_STATE_CHANGE_PAUSED_TO_READY
handling would be needed, together with actually starting the timers again later.
This then causes the streaming thread to wait there, the timer thread to wait on the same condition variable in wait_next_timeout
, and the flushing thread to wait forever for the streaming thread to shut down.
The timer condition variable handling (and also others) seems also rather fragile. Especially for the timer we have two threads waiting for the same condition variable and there is only ever a g_cond_signal()
.
For this and the other condition variables it seems like they're sometimes missing a loop to protect against spurious wakeups and also are sometimes missing an actual condition they check before/after being woken up.