diff options
author | Edward Hervey <edward@centricular.com> | 2017-11-16 18:22:20 +0100 |
---|---|---|
committer | Edward Hervey <bilboed@bilboed.com> | 2017-11-16 18:22:20 +0100 |
commit | 38c835ec1eeeaa377c0910fb31365bd151974503 (patch) | |
tree | 928c4962125a1a50eac7195fda99e9065ed2a242 /gst | |
parent | e72aa501b02dbaa6271d002e6d6cd23301960bb5 (diff) |
decodebin2: Don't spawn threads on shutdown
If we are shutting down, don't spawn a cleanup thread to cleanup old
groups and instead queue them to be cleaned up in the state change
thread.
This avoids (hopefully for good) having a race between the state change
thread and other threads trying to deactivate elements/pads.
Diffstat (limited to 'gst')
-rw-r--r-- | gst/playback/gstdecodebin2.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index a00efdb85..1def9106d 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -193,6 +193,7 @@ struct _GstDecodeBin * We store it to make sure we end up joining it * before stopping the element. * Protected by the object lock */ + GList *cleanup_groups; /* List of groups to free */ }; struct _GstDecodeBinClass @@ -3688,6 +3689,16 @@ gst_decode_chain_start_free_hidden_groups_thread (GstDecodeChain * chain) } chain->old_groups = NULL; + + if (dbin->shutdown) { + /* If we're shutting down, add the groups to be cleaned up in the + * state change handler (which *is* another thread). Also avoids + * playing racy games with the state change handler */ + dbin->cleanup_groups = g_list_concat (dbin->cleanup_groups, old_groups); + g_mutex_unlock (&dbin->cleanup_lock); + return; + } + thread = g_thread_try_new ("free-hidden-groups", (GThreadFunc) gst_decode_chain_free_hidden_groups, old_groups, &error); if (!thread || error) { @@ -5414,8 +5425,23 @@ gst_decode_bin_change_state (GstElement * element, GstStateChange transition) g_list_free_full (dbin->buffering_status, (GDestroyNotify) gst_message_unref); dbin->buffering_status = NULL; + /* Let's do a final check of leftover groups to free */ + g_mutex_lock (&dbin->cleanup_lock); + if (dbin->cleanup_groups) { + gst_decode_chain_free_hidden_groups (dbin->cleanup_groups); + dbin->cleanup_groups = NULL; + } + g_mutex_unlock (&dbin->cleanup_lock); break; case GST_STATE_CHANGE_READY_TO_NULL: + /* Let's do a final check of leftover groups to free */ + g_mutex_lock (&dbin->cleanup_lock); + if (dbin->cleanup_groups) { + gst_decode_chain_free_hidden_groups (dbin->cleanup_groups); + dbin->cleanup_groups = NULL; + } + g_mutex_unlock (&dbin->cleanup_lock); + break; default: break; } |