diff options
author | Mathieu Duponchelle <mathieu@centricular.com> | 2020-01-15 17:06:41 +0100 |
---|---|---|
committer | GStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org> | 2020-01-23 18:08:21 +0000 |
commit | 90f7e851f43e83d2f8759675f0c8e9f289a8b3cf (patch) | |
tree | 1d625efc61b00592b0ed06f35cc4f004817293dc | |
parent | b4948f69a03846559ceb0cdc41bed8ea84690474 (diff) |
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
-rw-r--r-- | gst/rtsp-server/rtsp-client.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/gst/rtsp-server/rtsp-client.c b/gst/rtsp-server/rtsp-client.c index b7b6f18..1339bd9 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 * |