diff options
author | Wim Taymans <wtaymans@redhat.com> | 2014-04-08 14:49:41 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2014-04-08 14:49:41 +0200 |
commit | fd5e949169d71fe23102d6120853e28ef45f5ae4 (patch) | |
tree | 63864eae29b4a6396b7b86a7a46a827ec9ed2baa | |
parent | 7f40d3d87f4a1f49a3a69f8374f56f4bde2d1918 (diff) |
media: release the state lock when going to NULL
Set our state to UNPREPARING and release the state-lock before
setting the pipeline to the NULL state. This way, any pad-added
callback will be able to take the state-lock and check that we are now
unpreparing instead of deadlocking.
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=727102
-rw-r--r-- | gst/rtsp-server/rtsp-media.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c index facc40f..ff40ec8 100644 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -1920,11 +1920,14 @@ pad_added_cb (GstElement * element, GstPad * pad, GstRTSPMedia * media) stream = gst_rtsp_media_create_stream (media, pay, pad); gst_object_unref (pay); - g_object_set_data (G_OBJECT (pad), "gst-rtsp-dynpad-stream", stream); - GST_INFO ("pad added %s:%s, stream %p", GST_DEBUG_PAD_NAME (pad), stream); g_rec_mutex_lock (&priv->state_lock); + if (priv->status != GST_RTSP_MEDIA_STATUS_PREPARING) + goto not_preparing; + + g_object_set_data (G_OBJECT (pad), "gst-rtsp-dynpad-stream", stream); + /* we will be adding elements below that will cause ASYNC_DONE to be * posted in the bus. We want to ignore those messages until the * pipeline really prerolled. */ @@ -1937,6 +1940,17 @@ pad_added_cb (GstElement * element, GstPad * pad, GstRTSPMedia * media) priv->adding = FALSE; g_rec_mutex_unlock (&priv->state_lock); + + return; + + /* ERRORS */ +not_preparing: + { + gst_rtsp_media_remove_stream (media, stream); + g_rec_mutex_unlock (&priv->state_lock); + GST_INFO ("ignore pad because we are not preparing"); + return; + } } static void @@ -2278,7 +2292,11 @@ finish_unprepare (GstRTSPMedia * media) GST_DEBUG ("shutting down"); + /* release the lock on shutdown, otherwise pad_added_cb might try to + * acquire the lock and then we deadlock */ + g_rec_mutex_unlock (&priv->state_lock); set_state (media, GST_STATE_NULL); + g_rec_mutex_lock (&priv->state_lock); remove_fakesink (priv); for (i = 0; i < priv->streams->len; i++) { |