Do some more session cleanup
authorWim Taymans <wim.taymans@collabora.co.uk>
Wed, 11 Mar 2009 18:38:06 +0000 (19:38 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Wed, 11 Mar 2009 18:38:06 +0000 (19:38 +0100)
Make session timeout kill the TCP connection that currently watches the
session.
Remove the client timeout property.

gst/rtsp-server/rtsp-client.c
gst/rtsp-server/rtsp-client.h
gst/rtsp-server/rtsp-session-pool.c

index 70b0e23..2476db7 100644 (file)
@@ -22,9 +22,7 @@
 #include "rtsp-client.h"
 #include "rtsp-sdp.h"
 
-#undef DEBUG
-
-#define DEFAULT_TIMEOUT  60
+#define DEBUG
 
 static GMutex *tunnels_lock;
 static GHashTable *tunnels;
@@ -32,7 +30,6 @@ static GHashTable *tunnels;
 enum
 {
   PROP_0,
-  PROP_TIMEOUT,
   PROP_SESSION_POOL,
   PROP_MEDIA_MAPPING,
   PROP_LAST
@@ -44,6 +41,8 @@ static void gst_rtsp_client_set_property (GObject *object, guint propid,
     const GValue *value, GParamSpec *pspec);
 static void gst_rtsp_client_finalize (GObject * obj);
 
+static void client_session_finalized (GstRTSPClient *client, GstRTSPSession *session);
+
 G_DEFINE_TYPE (GstRTSPClient, gst_rtsp_client, G_TYPE_OBJECT);
 
 static void
@@ -58,10 +57,6 @@ gst_rtsp_client_class_init (GstRTSPClientClass * klass)
   gobject_class->finalize = gst_rtsp_client_finalize;
 
   g_object_class_install_property (gobject_class, PROP_SESSION_POOL,
-      g_param_spec_uint ("timeout", "Timeout", "The client timeout",
-          0, G_MAXUINT, DEFAULT_TIMEOUT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_SESSION_POOL,
       g_param_spec_object ("session-pool", "Session Pool",
           "The session pool to use for client session",
           GST_TYPE_RTSP_SESSION_POOL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
@@ -78,7 +73,6 @@ gst_rtsp_client_class_init (GstRTSPClientClass * klass)
 static void
 gst_rtsp_client_init (GstRTSPClient * client)
 {
-  client->timeout = DEFAULT_TIMEOUT;
 }
 
 /* A client is finalized when the connection is broken */
@@ -86,9 +80,14 @@ static void
 gst_rtsp_client_finalize (GObject * obj)
 {
   GstRTSPClient *client = GST_RTSP_CLIENT (obj);
+  GList *walk;
 
   g_message ("finalize client %p", client);
 
+  for (walk = client->sessions; walk; walk = g_list_next (walk))
+    g_object_weak_unref (G_OBJECT (walk->data), (GWeakNotify) client_session_finalized, client);
+  g_list_free (client->sessions);
+
   gst_rtsp_connection_free (client->connection);
   if (client->session_pool)
     g_object_unref (client->session_pool);
@@ -110,9 +109,6 @@ gst_rtsp_client_get_property (GObject *object, guint propid,
   GstRTSPClient *client = GST_RTSP_CLIENT (object);
 
   switch (propid) {
-    case PROP_TIMEOUT:
-      g_value_set_uint (value, gst_rtsp_client_get_timeout (client));
-      break;
     case PROP_SESSION_POOL:
       g_value_take_object (value, gst_rtsp_client_get_session_pool (client));
       break;
@@ -131,9 +127,6 @@ gst_rtsp_client_set_property (GObject *object, guint propid,
   GstRTSPClient *client = GST_RTSP_CLIENT (object);
 
   switch (propid) {
-    case PROP_TIMEOUT:
-      gst_rtsp_client_set_timeout (client, g_value_get_uint (value));
-      break;
     case PROP_SESSION_POOL:
       gst_rtsp_client_set_session_pool (client, g_value_get_object (value));
       break;
@@ -163,16 +156,10 @@ gst_rtsp_client_new (void)
 static void
 send_response (GstRTSPClient *client, GstRTSPSession *session, GstRTSPMessage *response)
 {
-  GTimeVal timeout;
-
   gst_rtsp_message_add_header (response, GST_RTSP_HDR_SERVER, "GStreamer RTSP server");
 
-#ifdef DEBUG
-  gst_rtsp_message_dump (response);
-#endif
-
-  timeout.tv_sec = client->timeout;
-  timeout.tv_usec = 0;
+  /* remove any previous header */
+  gst_rtsp_message_remove_header (response, GST_RTSP_HDR_SESSION, -1);
 
   /* add the new session header for new session ids */
   if (session) {
@@ -185,10 +172,10 @@ send_response (GstRTSPClient *client, GstRTSPSession *session, GstRTSPMessage *r
 
     gst_rtsp_message_take_header (response, GST_RTSP_HDR_SESSION, str);
   }
-  else {
-    /* remove the session id from the response */
-    gst_rtsp_message_remove_header (response, GST_RTSP_HDR_SESSION, -1);
-  }
+
+#ifdef DEBUG
+  gst_rtsp_message_dump (response);
+#endif
 
   gst_rtsp_watch_queue_message (client->watch, response);
   gst_rtsp_message_unset (response);
@@ -807,7 +794,7 @@ handle_describe_request (GstRTSPClient *client, GstRTSPUrl *uri, GstRTSPSession
   gst_rtsp_message_take_body (&response, (guint8 *)str, strlen (str));
   gst_sdp_message_free (sdp);
 
-  send_response (client, NULL, &response);
+  send_response (client, session, &response);
 
   return TRUE;
 
@@ -847,7 +834,7 @@ handle_options_request (GstRTSPClient *client, GstRTSPUrl *uri, GstRTSPSession *
   gst_rtsp_message_add_header (&response, GST_RTSP_HDR_PUBLIC, str);
   g_free (str);
 
-  send_response (client, NULL, &response);
+  send_response (client, session, &response);
 }
 
 /* remove duplicate and trailing '/' */
@@ -878,6 +865,37 @@ santize_uri (GstRTSPUrl *uri)
 }
 
 static void
+client_session_finalized (GstRTSPClient *client, GstRTSPSession *session)
+{
+  g_message ("session %p finalized", session);
+
+  client->sessions = g_list_remove (client->sessions, session);
+  if (client->sessions == NULL) {
+    g_message ("all sessions finalized");
+    g_source_destroy ((GSource*)client->watch);
+  }
+}
+
+static void
+client_watch_session (GstRTSPClient *client, GstRTSPSession *session)
+{
+  GList *walk;
+
+  for (walk = client->sessions; walk; walk = g_list_next (walk)) {
+    GstRTSPSession *msession = (GstRTSPSession *) walk->data;
+
+    /* we already know about this session */
+    if (msession == session)
+      return;
+  }
+
+  g_message ("watching session %p", session);
+
+  g_object_weak_ref (G_OBJECT (session), (GWeakNotify) client_session_finalized, client);
+  client->sessions = g_list_prepend (client->sessions, session);
+}
+
+static void
 handle_request (GstRTSPClient *client, GstRTSPMessage *request)
 {
   GstRTSPMethod method;
@@ -921,7 +939,7 @@ handle_request (GstRTSPClient *client, GstRTSPMessage *request)
     if (!(session = gst_rtsp_session_pool_find (client->session_pool, sessid)))
       goto session_not_found;
 
-    client->timeout = gst_rtsp_session_get_timeout (session);
+    client_watch_session (client, session);
   }
   else
     session = NULL;
@@ -1026,33 +1044,6 @@ handle_data (GstRTSPClient *client, GstRTSPMessage *message)
 }
 
 /**
- * gst_rtsp_client_set_timeout:
- * @client: a #GstRTSPClient
- * @timeout: a timeout in seconds
- *
- * Set the connection timeout to @timeout seconds for @client.
- */
-void
-gst_rtsp_client_set_timeout (GstRTSPClient *client, guint timeout)
-{
-  client->timeout = timeout;
-}
-
-/**
- * gst_rtsp_client_get_timeout:
- * @client: a #GstRTSPClient
- *
- * Get the connection timeout @client.
- *
- * Returns: the connection timeout for @client in seconds.
- */
-guint
-gst_rtsp_client_get_timeout (GstRTSPClient *client)
-{
-  return client->timeout;
-}
-
-/**
  * gst_rtsp_client_set_session_pool:
  * @client: a #GstRTSPClient
  * @pool: a #GstRTSPSessionPool
index 07b81d9..ab124c0 100644 (file)
@@ -61,12 +61,12 @@ typedef struct _GstRTSPClientClass GstRTSPClientClass;
  * @connection: the connection object handling the client request.
  * @watch: watch for the connection
  * @watchid: id of the watch
- * @timeout: the session timeout
  * @session_pool: handle to the session pool used by the client.
  * @media_mapping: handle to the media mapping used by the client.
  * @uri: cached uri
  * @media: cached media
  * @streams: a list of streams using @connection.
+ * @sessions: a list of sessions managed by @connection.
  *
  * The client structure.
  */
@@ -77,7 +77,6 @@ struct _GstRTSPClient {
   GstRTSPWatch      *watch;
   guint              watchid;
 
-  guint                 timeout;
   GstRTSPSessionPool   *session_pool;
   GstRTSPMediaMapping  *media_mapping;
 
@@ -85,6 +84,7 @@ struct _GstRTSPClient {
   GstRTSPMedia   *media;
 
   GList *streams;
+  GList *sessions;
 };
 
 struct _GstRTSPClientClass {
@@ -103,9 +103,6 @@ void                  gst_rtsp_client_set_media_mapping (GstRTSPClient *client,
                                                          GstRTSPMediaMapping *mapping);
 GstRTSPMediaMapping * gst_rtsp_client_get_media_mapping (GstRTSPClient *client);
 
-void                  gst_rtsp_client_set_timeout       (GstRTSPClient *client, guint timeout);
-guint                 gst_rtsp_client_get_timeout       (GstRTSPClient *client);
-
 gboolean              gst_rtsp_client_accept            (GstRTSPClient *client, 
                                                          GIOChannel *channel);
 
index 44d749b..d8702a9 100644 (file)
@@ -214,13 +214,11 @@ gst_rtsp_session_pool_find (GstRTSPSessionPool *pool, const gchar *sessionid)
 
   g_mutex_lock (pool->lock);
   result = g_hash_table_lookup (pool->sessions, sessionid);
-  if (result) 
-    g_object_ref (result);
-  g_mutex_unlock (pool->lock);
-
   if (result) {
+    g_object_ref (result);
     gst_rtsp_session_touch (result);
   }
+  g_mutex_unlock (pool->lock);
 
   return result;
 }