From 90f7e851f43e83d2f8759675f0c8e9f289a8b3cf Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Wed, 15 Jan 2020 17:06:41 +0100 Subject: [PATCH] rtsp-client: make closing more thread safe + Take the watch lock prior to using priv->watch + Flush both the watch and connection before closing / unreffing gst_rtsp_connection_close() is not threadsafe on its own, this is a workaround at the client level, where we control both the watch and the connection --- gst/rtsp-server/rtsp-client.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/gst/rtsp-server/rtsp-client.c b/gst/rtsp-server/rtsp-client.c index b7b6f18cb4..1339bd976b 100644 --- a/gst/rtsp-server/rtsp-client.c +++ b/gst/rtsp-server/rtsp-client.c @@ -1292,6 +1292,13 @@ gst_rtsp_client_close (GstRTSPClient * client) GST_DEBUG ("client %p: closing connection", client); + g_mutex_lock (&priv->watch_lock); + + /* Work around the lack of thread safety of gst_rtsp_connection_close */ + if (priv->watch) { + gst_rtsp_watch_set_flushing (priv->watch, TRUE); + } + if (priv->connection) { if ((tunnelid = gst_rtsp_connection_get_tunnelid (priv->connection))) { g_mutex_lock (&tunnels_lock); @@ -1299,11 +1306,10 @@ gst_rtsp_client_close (GstRTSPClient * client) g_hash_table_remove (tunnels, tunnelid); g_mutex_unlock (&tunnels_lock); } + gst_rtsp_connection_flush (priv->connection, TRUE); gst_rtsp_connection_close (priv->connection); } - /* connection is now closed, destroy the watch which will also cause the - * closed signal to be emitted */ if (priv->watch) { GST_DEBUG ("client %p: destroying watch", client); g_source_destroy ((GSource *) priv->watch); @@ -1314,6 +1320,8 @@ gst_rtsp_client_close (GstRTSPClient * client) g_main_context_unref (priv->watch_context); priv->watch_context = NULL; } + + g_mutex_unlock (&priv->watch_lock); } static gchar *