From 5d8abd9bfd3bbf8ae31b0c8970bf1338dc56a593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 14 May 2020 10:08:32 +0300 Subject: [PATCH] rtsp-client: Fix some race conditions around timeout source removal We always need to take the lock while accessing it as otherwise another thread might've removed it in the meantime. Also when destroying and creating a new one, ensure that the mutex is not shortly unlocked in between as during that time another one might potentially be created already. Part-of: --- gst/rtsp-server/rtsp-client.c | 46 ++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/gst/rtsp-server/rtsp-client.c b/gst/rtsp-server/rtsp-client.c index b3fbefcba8..32f2f0dde5 100644 --- a/gst/rtsp-server/rtsp-client.c +++ b/gst/rtsp-server/rtsp-client.c @@ -2539,6 +2539,27 @@ make_server_transport (GstRTSPClient * client, GstRTSPMedia * media, return st; } +static void +rtsp_ctrl_timeout_remove_unlocked (GstRTSPClientPrivate * priv) +{ + if (priv->rtsp_ctrl_timeout != NULL) { + GST_DEBUG ("rtsp control session removed timeout %p.", + priv->rtsp_ctrl_timeout); + g_source_destroy (priv->rtsp_ctrl_timeout); + g_source_unref (priv->rtsp_ctrl_timeout); + priv->rtsp_ctrl_timeout = NULL; + priv->rtsp_ctrl_timeout_cnt = 0; + } +} + +static void +rtsp_ctrl_timeout_remove (GstRTSPClientPrivate * priv) +{ + g_mutex_lock (&priv->lock); + rtsp_ctrl_timeout_remove_unlocked (priv); + g_mutex_unlock (&priv->lock); +} + static gboolean rtsp_ctrl_timeout_cb (gpointer user_data) { @@ -2552,12 +2573,10 @@ rtsp_ctrl_timeout_cb (gpointer user_data) && priv->rtsp_ctrl_timeout_cnt > RTSP_CTRL_TIMEOUT_VALUE) || (priv->had_session && priv->rtsp_ctrl_timeout_cnt > priv->post_session_timeout)) { + g_mutex_lock (&priv->lock); GST_DEBUG ("rtsp control session timeout %p expired, closing client.", priv->rtsp_ctrl_timeout); - g_mutex_lock (&priv->lock); - g_source_unref (priv->rtsp_ctrl_timeout); - priv->rtsp_ctrl_timeout = NULL; - priv->rtsp_ctrl_timeout_cnt = 0; + rtsp_ctrl_timeout_remove_unlocked (priv); g_mutex_unlock (&priv->lock); gst_rtsp_client_close (client); @@ -2567,23 +2586,6 @@ rtsp_ctrl_timeout_cb (gpointer user_data) return res; } -static void -rtsp_ctrl_timeout_remove (GstRTSPClientPrivate * priv) -{ - g_mutex_lock (&priv->lock); - - if (priv->rtsp_ctrl_timeout != NULL) { - GST_DEBUG ("rtsp control session removed timeout %p.", - priv->rtsp_ctrl_timeout); - g_source_destroy (priv->rtsp_ctrl_timeout); - g_source_unref (priv->rtsp_ctrl_timeout); - priv->rtsp_ctrl_timeout = NULL; - priv->rtsp_ctrl_timeout_cnt = 0; - } - - g_mutex_unlock (&priv->lock); -} - static gchar * stream_make_keymgmt (GstRTSPClient * client, const gchar * location, GstRTSPStream * stream) @@ -5201,8 +5203,8 @@ gst_rtsp_client_attach (GstRTSPClient * client, GMainContext * context) /* Setting up a timeout for the RTSP control channel until a session * is up where it is handling timeouts. */ - rtsp_ctrl_timeout_remove (priv); /* removing old if any */ g_mutex_lock (&priv->lock); + rtsp_ctrl_timeout_remove_unlocked (priv); /* removing old if any */ timer_src = g_timeout_source_new_seconds (RTSP_CTRL_CB_INTERVAL); g_source_set_callback (timer_src, rtsp_ctrl_timeout_cb, client, NULL);