static void client_session_finalized (GstRTSPClient * client,
GstRTSPSession * session);
-static void unlink_streams (GstRTSPClient * client);
-
G_DEFINE_TYPE (GstRTSPClient, gst_rtsp_client, G_TYPE_OBJECT);
static void
(GWeakNotify) client_session_finalized, client);
}
- unlink_streams (client);
-
g_list_free (client->sessions);
gst_rtsp_connection_free (client->connection);
client->streams = g_list_remove (client->streams, stream);
}
-static void
-unlink_streams (GstRTSPClient * client)
-{
- GList *walk;
-
- GST_DEBUG ("client %p: unlinking streams", client);
- for (walk = client->streams; walk; walk = g_list_next (walk)) {
- GstRTSPSessionStream *stream = (GstRTSPSessionStream *) walk->data;
-
- gst_rtsp_session_stream_set_callbacks (stream, NULL, NULL, NULL, NULL);
- }
- g_list_free (client->streams);
- client->streams = NULL;
-}
-
static void
unlink_session_streams (GstRTSPClient * client, GstRTSPSessionMedia * media)
{
}
}
+static void
+close_connection (GstRTSPClient * client)
+{
+ const gchar * tunnelid;
+
+ GST_DEBUG ("client %p: closing connection", client);
+
+ if ((tunnelid = gst_rtsp_connection_get_tunnelid (client->connection))) {
+ g_mutex_lock (tunnels_lock);
+ /* remove from tunnelids */
+ g_hash_table_remove (tunnels, tunnelid);
+ g_mutex_unlock (tunnels_lock);
+ }
+
+ gst_rtsp_connection_close (client->connection);
+ if (client->watchid) {
+ g_source_destroy ((GSource *) client->watch);
+ client->watchid = 0;
+ client->watch = NULL;
+ }
+}
+
static gboolean
handle_teardown_request (GstRTSPClient * client, GstRTSPUrl * uri,
GstRTSPSession * session, GstRTSPMessage * request)
send_response (client, session, &response);
- GST_DEBUG ("client %p: closing connection", client);
- if (client->watchid) {
- g_source_destroy ((GSource *) client->watch);
- client->watchid = 0;
- }
- gst_rtsp_connection_close (client->connection);
+ close_connection (client);
return TRUE;
static void
client_session_finalized (GstRTSPClient * client, GstRTSPSession * session)
{
+ GList *medias;
+
+ GST_INFO ("client %p: session %p finished", client, session);
+
+ /* unlink all media managed in this session */
+ for (medias = session->medias; medias; medias = g_list_next (medias)) {
+ unlink_session_streams (client, (GstRTSPSessionMedia *) medias->data);
+ }
+
if (!(client->sessions = g_list_remove (client->sessions, session))) {
- GST_INFO ("all sessions finalized, close the connection");
- g_source_destroy ((GSource *) client->watch);
- client->watchid = 0;
+ GST_INFO ("client %p: all sessions finalized, close the connection", client);
+ close_connection (client);
}
}
g_mutex_unlock (tunnels_lock);
}
- /* remove all streams that are streaming over this client connection */
- unlink_streams (client);
-
return GST_RTSP_OK;
}
* remove the ref to it. */
g_object_ref (oclient);
g_hash_table_remove (tunnels, tunnelid);
+
+ if (oclient->watch == NULL)
+ goto tunnel_closed;
g_mutex_unlock (tunnels_lock);
GST_INFO ("client %p: found tunnel %p (old %p, new %p)", client, oclient,
/* we don't need this watch anymore */
g_source_destroy ((GSource *) client->watch);
client->watchid = 0;
+ client->watch = NULL;
return GST_RTSP_OK;
GST_INFO ("client %p: tunnel session %s not found", client, tunnelid);
return GST_RTSP_STS_SERVICE_UNAVAILABLE;
}
+tunnel_closed:
+ {
+ g_mutex_unlock (tunnels_lock);
+ GST_INFO ("client %p: tunnel session %s was closed", client, tunnelid);
+ g_object_unref (oclient);
+ return GST_RTSP_STS_SERVICE_UNAVAILABLE;
+ }
}
static GstRTSPWatchFuncs watch_funcs = {
{
GST_INFO ("client %p: watch destroyed", client);
client->watchid = 0;
+ client->watch = NULL;
g_object_unref (client);
}