diff options
author | Göran Jönsson <goranjn@axis.com> | 2014-08-28 13:35:15 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2014-09-04 12:53:57 +0300 |
commit | f62b4c4dfbb5bf22dcabde4084cfcf989600749c (patch) | |
tree | 47a4f6b2c54191a3539442d258594d6f2524c495 /gst/rtsp-server/rtsp-client.c | |
parent | f41dad780915ed1ef3d38d1a179a144d8ff331ab (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
Diffstat (limited to 'gst/rtsp-server/rtsp-client.c')
-rw-r--r-- | gst/rtsp-server/rtsp-client.c | 8 |
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; } |