splitmuxsink: prevent deadlock when states change too fast

If the GOP is completed, pads have to start gathering for the
next one but it is possible that the the state might go to
COLLECTING_GOP_START and back to WAITING_GOP_COMPLETE before the
thread has a chance to wake up and proceed, leaving it trapped in
the check_completed_gop loop and deadlocking the other threads
waiting for it to advance.

To solve it, this patch also checks that tha input running time
hasn't changed to prevent this scenario.
This commit is contained in:
Thiago Santos 2015-08-03 13:42:20 -03:00
parent ef7863355c
commit a930a1364a

View file

@ -832,6 +832,7 @@ check_completed_gop (GstSplitMuxSink * splitmux, MqStreamCtx * ctx)
{ {
GList *cur; GList *cur;
gboolean ready = TRUE; gboolean ready = TRUE;
GstClockTime current_max_in_running_time;
if (splitmux->state == SPLITMUX_STATE_WAITING_GOP_COMPLETE) { if (splitmux->state == SPLITMUX_STATE_WAITING_GOP_COMPLETE) {
/* Iterate each pad, and check that the input running time is at least /* Iterate each pad, and check that the input running time is at least
@ -865,9 +866,11 @@ check_completed_gop (GstSplitMuxSink * splitmux, MqStreamCtx * ctx)
/* Some pad is not yet ready, or GOP is being pushed /* Some pad is not yet ready, or GOP is being pushed
* either way, sleep and wait to get woken */ * either way, sleep and wait to get woken */
current_max_in_running_time = splitmux->max_in_running_time;
while ((splitmux->state == SPLITMUX_STATE_WAITING_GOP_COMPLETE || while ((splitmux->state == SPLITMUX_STATE_WAITING_GOP_COMPLETE ||
splitmux->state == SPLITMUX_STATE_START_NEXT_FRAGMENT) && splitmux->state == SPLITMUX_STATE_START_NEXT_FRAGMENT) &&
!ctx->flushing) { !ctx->flushing &&
(current_max_in_running_time == splitmux->max_in_running_time)) {
GST_LOG_OBJECT (splitmux, "Sleeping for %s (ctx %p)", GST_LOG_OBJECT (splitmux, "Sleeping for %s (ctx %p)",
splitmux->state == SPLITMUX_STATE_WAITING_GOP_COMPLETE ? splitmux->state == SPLITMUX_STATE_WAITING_GOP_COMPLETE ?