summaryrefslogtreecommitdiff
path: root/ext/hls/gsthlsdemux.c
diff options
context:
space:
mode:
authorCharlie Turner <cturner@igalia.com>2019-07-02 12:27:40 +0100
committerCharlie Turner <cturner@igalia.com>2019-07-29 13:19:41 +0100
commit659d76a633641292be68459f5e4496c04059622d (patch)
tree8738cefd12c3a1d4d8175201333696f8b98e01b1 /ext/hls/gsthlsdemux.c
parente898f1565d5e90f03adfd68558ccb004a41341f2 (diff)
downloadgstreamer-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.c8
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;