decodebin2: Avoid deactivation races

Deactivating pads from two threads isn't 100% MT-safe. There is a
slim chance that the GstPadActivateFunc might be called twice with
the same values (in this case from the cleanup thread *and* from
the GstElement change_state function when going from PAUSED to READY).

In order to avoid that, call any existing cleanup function *before*
calling the parent change_state implementation on downwards state
changes.
This commit is contained in:
Edward Hervey 2017-11-16 06:39:41 +01:00 committed by Edward Hervey
parent 4c2f91d69e
commit e72aa501b0

View file

@ -5372,6 +5372,17 @@ gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
dbin->shutdown = TRUE; dbin->shutdown = TRUE;
unblock_pads (dbin); unblock_pads (dbin);
DYN_UNLOCK (dbin); DYN_UNLOCK (dbin);
/* Make sure we don't have cleanup races where
* we might be trying to deactivate pads (in the cleanup thread)
* at the same time as the default element deactivation
* (in PAUSED=>READY) */
g_mutex_lock (&dbin->cleanup_lock);
if (dbin->cleanup_thread) {
g_thread_join (dbin->cleanup_thread);
dbin->cleanup_thread = NULL;
}
g_mutex_unlock (&dbin->cleanup_lock);
default: default:
break; break;
} }
@ -5405,12 +5416,6 @@ gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
dbin->buffering_status = NULL; dbin->buffering_status = NULL;
break; break;
case GST_STATE_CHANGE_READY_TO_NULL: case GST_STATE_CHANGE_READY_TO_NULL:
g_mutex_lock (&dbin->cleanup_lock);
if (dbin->cleanup_thread) {
g_thread_join (dbin->cleanup_thread);
dbin->cleanup_thread = NULL;
}
g_mutex_unlock (&dbin->cleanup_lock);
default: default:
break; break;
} }