summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorEdward Hervey <edward@centricular.com>2017-11-16 18:22:20 +0100
committerEdward Hervey <bilboed@bilboed.com>2017-11-16 18:22:20 +0100
commit38c835ec1eeeaa377c0910fb31365bd151974503 (patch)
tree928c4962125a1a50eac7195fda99e9065ed2a242 /gst
parente72aa501b02dbaa6271d002e6d6cd23301960bb5 (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.c26
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;
}