mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
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
This commit is contained in:
parent
1b47b6d9b0
commit
09bf2025f8
1 changed files with 8 additions and 0 deletions
|
@ -59,6 +59,7 @@ struct _GstRTSPClientPrivate
|
||||||
{
|
{
|
||||||
GMutex lock; /* protects everything else */
|
GMutex lock; /* protects everything else */
|
||||||
GMutex send_lock;
|
GMutex send_lock;
|
||||||
|
GMutex watch_lock;
|
||||||
GstRTSPConnection *connection;
|
GstRTSPConnection *connection;
|
||||||
GstRTSPWatch *watch;
|
GstRTSPWatch *watch;
|
||||||
GMainContext *watch_context;
|
GMainContext *watch_context;
|
||||||
|
@ -278,6 +279,7 @@ gst_rtsp_client_init (GstRTSPClient * client)
|
||||||
|
|
||||||
g_mutex_init (&priv->lock);
|
g_mutex_init (&priv->lock);
|
||||||
g_mutex_init (&priv->send_lock);
|
g_mutex_init (&priv->send_lock);
|
||||||
|
g_mutex_init (&priv->watch_lock);
|
||||||
priv->close_seq = 0;
|
priv->close_seq = 0;
|
||||||
priv->drop_backlog = DEFAULT_DROP_BACKLOG;
|
priv->drop_backlog = DEFAULT_DROP_BACKLOG;
|
||||||
}
|
}
|
||||||
|
@ -406,6 +408,7 @@ gst_rtsp_client_finalize (GObject * obj)
|
||||||
g_free (priv->server_ip);
|
g_free (priv->server_ip);
|
||||||
g_mutex_clear (&priv->lock);
|
g_mutex_clear (&priv->lock);
|
||||||
g_mutex_clear (&priv->send_lock);
|
g_mutex_clear (&priv->send_lock);
|
||||||
|
g_mutex_clear (&priv->watch_lock);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gst_rtsp_client_parent_class)->finalize (obj);
|
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);
|
gst_rtsp_watch_set_flushing (watch, TRUE);
|
||||||
|
g_mutex_lock (&priv->watch_lock);
|
||||||
gst_rtsp_client_set_send_func (client, NULL, NULL, NULL);
|
gst_rtsp_client_set_send_func (client, NULL, NULL, NULL);
|
||||||
|
g_mutex_unlock (&priv->watch_lock);
|
||||||
|
|
||||||
return GST_RTSP_OK;
|
return GST_RTSP_OK;
|
||||||
}
|
}
|
||||||
|
@ -3284,6 +3289,7 @@ handle_tunnel (GstRTSPClient * client)
|
||||||
|
|
||||||
opriv = oclient->priv;
|
opriv = oclient->priv;
|
||||||
|
|
||||||
|
g_mutex_lock (&opriv->watch_lock);
|
||||||
if (opriv->watch == NULL)
|
if (opriv->watch == NULL)
|
||||||
goto tunnel_closed;
|
goto tunnel_closed;
|
||||||
|
|
||||||
|
@ -3293,6 +3299,7 @@ handle_tunnel (GstRTSPClient * client)
|
||||||
gst_rtsp_connection_do_tunnel (opriv->connection, priv->connection);
|
gst_rtsp_connection_do_tunnel (opriv->connection, priv->connection);
|
||||||
gst_rtsp_watch_reset (priv->watch);
|
gst_rtsp_watch_reset (priv->watch);
|
||||||
gst_rtsp_watch_reset (opriv->watch);
|
gst_rtsp_watch_reset (opriv->watch);
|
||||||
|
g_mutex_unlock (&opriv->watch_lock);
|
||||||
g_object_unref (oclient);
|
g_object_unref (oclient);
|
||||||
|
|
||||||
/* the old client owns the tunnel now, the new one will be freed */
|
/* the old client owns the tunnel now, the new one will be freed */
|
||||||
|
@ -3312,6 +3319,7 @@ no_tunnelid:
|
||||||
tunnel_closed:
|
tunnel_closed:
|
||||||
{
|
{
|
||||||
GST_ERROR ("client %p: tunnel session %s was closed", client, tunnelid);
|
GST_ERROR ("client %p: tunnel session %s was closed", client, tunnelid);
|
||||||
|
g_mutex_unlock (&opriv->watch_lock);
|
||||||
g_object_unref (oclient);
|
g_object_unref (oclient);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue