/* GStreamer * Copyright (C) 2008 Wim Taymans * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rtsp-session-pool.h" #undef DEBUG static void gst_rtsp_session_pool_finalize (GObject * object); static gchar * create_session_id (GstRTSPSessionPool *pool); G_DEFINE_TYPE (GstRTSPSessionPool, gst_rtsp_session_pool, G_TYPE_OBJECT); static void gst_rtsp_session_pool_class_init (GstRTSPSessionPoolClass * klass) { GObjectClass *gobject_class; gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = gst_rtsp_session_pool_finalize; klass->create_session_id = create_session_id; } static void gst_rtsp_session_pool_init (GstRTSPSessionPool * pool) { pool->lock = g_mutex_new (); pool->sessions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); } static void gst_rtsp_session_pool_finalize (GObject * object) { GstRTSPSessionPool * pool = GST_RTSP_SESSION_POOL (object); g_mutex_free (pool->lock); g_hash_table_unref (pool->sessions); G_OBJECT_CLASS (gst_rtsp_session_pool_parent_class)->finalize (object); } /** * gst_rtsp_session_pool_new: * * Create a new #GstRTSPSessionPool instance. * * Returns: A new #GstRTSPSessionPool. g_object_unref() after usage. */ GstRTSPSessionPool * gst_rtsp_session_pool_new (void) { GstRTSPSessionPool *result; result = g_object_new (GST_TYPE_RTSP_SESSION_POOL, NULL); return result; } /** * gst_rtsp_session_pool_find: * @pool: the pool to search * @sessionid: the session id * * Find the session with @sessionid in @pool. * * Returns: the #GstRTSPSession with @sessionid or %NULL when the session did * not exist. g_object_unref() after usage. */ GstRTSPSession * gst_rtsp_session_pool_find (GstRTSPSessionPool *pool, const gchar *sessionid) { GstRTSPSession *result; g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), NULL); g_return_val_if_fail (sessionid != NULL, NULL); g_mutex_lock (pool->lock); result = g_hash_table_lookup (pool->sessions, sessionid); if (result) g_object_ref (result); g_mutex_unlock (pool->lock); return result; } static gchar * create_session_id (GstRTSPSessionPool *pool) { gchar id[16]; gint i; for (i = 0; i < 16; i++) { id[i] = g_random_int_range ('a', 'z'); } return g_strndup (id, 16); } /** * gst_rtsp_session_pool_create: * @pool: a #GstRTSPSessionPool * * Create a new #GstRTSPSession object in @pool. * * Returns: a new #GstRTSPSession. */ GstRTSPSession * gst_rtsp_session_pool_create (GstRTSPSessionPool *pool) { GstRTSPSession *result = NULL; GstRTSPSessionPoolClass *klass; gchar *id = NULL; g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), NULL); klass = GST_RTSP_SESSION_POOL_GET_CLASS (pool); do { /* start by creating a new random session id, we assume that this is random * enough to not cause a collision, which we will check later */ if (klass->create_session_id) id = klass->create_session_id (pool); else goto no_function; if (id == NULL) goto no_session; g_mutex_lock (pool->lock); /* check if the sessionid existed */ result = g_hash_table_lookup (pool->sessions, id); if (result) { /* found, retry with a different session id*/ result = NULL; } else { /* not found, create session and insert it in the pool */ result = gst_rtsp_session_new (id); /* take additional ref for the pool */ g_object_ref (result); g_hash_table_insert (pool->sessions, result->sessionid, result); } g_mutex_unlock (pool->lock); g_free (id); } while (result == NULL); return result; /* ERRORS */ no_function: { g_warning ("no create_session_id vmethod in GstRTSPSessionPool %p", pool); return NULL; } no_session: { g_warning ("can't create session id with GstRTSPSessionPool %p", pool); return NULL; } } /** * gst_rtsp_session_pool_remove: * @pool: a #GstRTSPSessionPool * @sess: a #GstRTSPSession * * Remove @sess from @pool and Clean it up. * * Returns: a new #GstRTSPSession. */ void gst_rtsp_session_pool_remove (GstRTSPSessionPool *pool, GstRTSPSession *sess) { gboolean found; g_return_if_fail (GST_IS_RTSP_SESSION_POOL (pool)); g_return_if_fail (GST_IS_RTSP_SESSION (sess)); g_mutex_lock (pool->lock); found = g_hash_table_remove (pool->sessions, sess); g_mutex_unlock (pool->lock); }