diff options
author | Charlie Turner <cturner@igalia.com> | 2019-07-02 12:27:40 +0100 |
---|---|---|
committer | Charlie Turner <cturner@igalia.com> | 2019-07-29 13:19:41 +0100 |
commit | 659d76a633641292be68459f5e4496c04059622d (patch) | |
tree | 8738cefd12c3a1d4d8175201333696f8b98e01b1 /ext/hls/gsthlsdemux.c | |
parent | e898f1565d5e90f03adfd68558ccb004a41341f2 (diff) | |
download | gstreamer-plugins-bad-659d76a633641292be68459f5e4496c04059622d.tar.gz |
adaptivedemux: remove some deadlocks using webkitwebsrc.
WebKit's websrc depends on the main-thread for download completion
rendezvous. This exposed a number of deadlocks in adaptivedemux due to
it holding the MANIFEST_LOCK during network requests, and also needing
to hold it to change_state and resolve queries, which frequently occur
during these download windows.
Make demux->running MT-safe so that it can be accessed without using the
MANIFEST_LOCK. In case a source is downloading and requires a MT-thread
notification for completion of the fragment download, a state change
during this download window will deadlock unless we cancel the downloads
and ensure they are not restarted before we finish the state-change.
Also make demux->priv->have_manifest MT-safe. A duration query happening
in the window described above can deadlock for the same reason. Other
src queries (like SEEKING) that happen in this window also could
deadlock, but I haven't hit this scenario.
Increase granularity of API_LOCK'ing in change_state as well. We need to
cancel downloads before trying to take this lock, since sink events
(EOS) will hold it before starting a fragment download.
Diffstat (limited to 'ext/hls/gsthlsdemux.c')
-rw-r--r-- | ext/hls/gsthlsdemux.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/ext/hls/gsthlsdemux.c b/ext/hls/gsthlsdemux.c index d4ca55634..1e4d0df90 100644 --- a/ext/hls/gsthlsdemux.c +++ b/ext/hls/gsthlsdemux.c @@ -73,6 +73,7 @@ static gboolean gst_hls_demux_update_playlist (GstHLSDemux * demux, gboolean update, GError ** err); static gchar *gst_hls_src_buf_to_utf8_playlist (GstBuffer * buf); +/* FIXME: the return value is never used? */ static gboolean gst_hls_demux_change_playlist (GstHLSDemux * demux, guint max_bitrate, gboolean * changed); static GstBuffer *gst_hls_demux_decrypt_fragment (GstHLSDemux * demux, @@ -1173,6 +1174,8 @@ gst_hls_demux_reset (GstAdaptiveDemux * ademux) { GstHLSDemux *demux = GST_HLS_DEMUX_CAST (ademux); + GST_DEBUG_OBJECT (demux, "resetting"); + GST_M3U8_CLIENT_LOCK (hlsdemux->client); if (demux->master) { gst_hls_master_playlist_unref (demux->master); @@ -1394,7 +1397,8 @@ retry: if (download == NULL) { gchar *base_uri; - if (!update || main_checked || demux->master->is_simple) { + if (!update || main_checked || demux->master->is_simple + || !gst_adaptive_demux_is_running (GST_ADAPTIVE_DEMUX_CAST (demux))) { g_free (uri); return FALSE; } @@ -1627,7 +1631,7 @@ retry_failover_protection: if (changed) *changed = TRUE; stream->discont = TRUE; - } else { + } else if (gst_adaptive_demux_is_running (GST_ADAPTIVE_DEMUX_CAST (demux))) { GstHLSVariantStream *failover_variant = NULL; GList *failover; |