summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGöran Jönsson <goranjn@axis.com>2014-08-28 13:35:15 +0200
committerSebastian Dröge <sebastian@centricular.com>2014-09-04 10:35:56 +0300
commit09bf2025f810cdad3127162dcce80a7dc73099e0 (patch)
tree43a726d1909f59a6d7d5fd00094b296f958d7e33
parent1b47b6d9b03bf93c3e5b0a2885c51851ef61d1e6 (diff)
rtsp-client: Protect saved clients watch with a mutex
Fixes a crash when close() is called while merging clients in handle_tunnel(). In that case close() would destroy the watch while it is still being used in handle_tunnel(). https://bugzilla.gnome.org/show_bug.cgi?id=735570
-rw-r--r--gst/rtsp-server/rtsp-client.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/gst/rtsp-server/rtsp-client.c b/gst/rtsp-server/rtsp-client.c
index d37fb68..77dc1d0 100644
--- a/gst/rtsp-server/rtsp-client.c
+++ b/gst/rtsp-server/rtsp-client.c
@@ -59,6 +59,7 @@ struct _GstRTSPClientPrivate
{
GMutex lock; /* protects everything else */
GMutex send_lock;
+ GMutex watch_lock;
GstRTSPConnection *connection;
GstRTSPWatch *watch;
GMainContext *watch_context;
@@ -278,6 +279,7 @@ gst_rtsp_client_init (GstRTSPClient * client)
g_mutex_init (&priv->lock);
g_mutex_init (&priv->send_lock);
+ g_mutex_init (&priv->watch_lock);
priv->close_seq = 0;
priv->drop_backlog = DEFAULT_DROP_BACKLOG;
}
@@ -406,6 +408,7 @@ gst_rtsp_client_finalize (GObject * obj)
g_free (priv->server_ip);
g_mutex_clear (&priv->lock);
g_mutex_clear (&priv->send_lock);
+ g_mutex_clear (&priv->watch_lock);
G_OBJECT_CLASS (gst_rtsp_client_parent_class)->finalize (obj);
}
@@ -3164,7 +3167,9 @@ closed (GstRTSPWatch * watch, gpointer user_data)
}
gst_rtsp_watch_set_flushing (watch, TRUE);
+ g_mutex_lock (&priv->watch_lock);
gst_rtsp_client_set_send_func (client, NULL, NULL, NULL);
+ g_mutex_unlock (&priv->watch_lock);
return GST_RTSP_OK;
}
@@ -3284,6 +3289,7 @@ handle_tunnel (GstRTSPClient * client)
opriv = oclient->priv;
+ g_mutex_lock (&opriv->watch_lock);
if (opriv->watch == NULL)
goto tunnel_closed;
@@ -3293,6 +3299,7 @@ handle_tunnel (GstRTSPClient * client)
gst_rtsp_connection_do_tunnel (opriv->connection, priv->connection);
gst_rtsp_watch_reset (priv->watch);
gst_rtsp_watch_reset (opriv->watch);
+ g_mutex_unlock (&opriv->watch_lock);
g_object_unref (oclient);
/* the old client owns the tunnel now, the new one will be freed */
@@ -3312,6 +3319,7 @@ no_tunnelid:
tunnel_closed:
{
GST_ERROR ("client %p: tunnel session %s was closed", client, tunnelid);
+ g_mutex_unlock (&opriv->watch_lock);
g_object_unref (oclient);
return FALSE;
}