session-pool: add session-removed signal

Add a signal to be notified when a session is removed from the pool.
This commit is contained in:
Wim Taymans 2014-06-30 15:14:34 +02:00
parent 41d1ef7ed3
commit 964ca3c988
2 changed files with 60 additions and 9 deletions

View file

@ -69,6 +69,14 @@ static const gchar session_id_charset[] =
'8', '9', '$', '-', '_', '.', '+' '8', '9', '$', '-', '_', '.', '+'
}; };
enum
{
SIGNAL_SESSION_REMOVED,
SIGNAL_LAST
};
static guint gst_rtsp_session_pool_signals[SIGNAL_LAST] = { 0 };
GST_DEBUG_CATEGORY_STATIC (rtsp_session_debug); GST_DEBUG_CATEGORY_STATIC (rtsp_session_debug);
#define GST_CAT_DEFAULT rtsp_session_debug #define GST_CAT_DEFAULT rtsp_session_debug
@ -103,6 +111,12 @@ gst_rtsp_session_pool_class_init (GstRTSPSessionPoolClass * klass)
0, G_MAXUINT, DEFAULT_MAX_SESSIONS, 0, G_MAXUINT, DEFAULT_MAX_SESSIONS,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_rtsp_session_pool_signals[SIGNAL_SESSION_REMOVED] =
g_signal_new ("session-removed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPSessionPoolClass,
session_removed), NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE,
1, GST_TYPE_RTSP_SESSION);
klass->create_session_id = create_session_id; klass->create_session_id = create_session_id;
klass->create_session = create_session; klass->create_session = create_session;
@ -123,14 +137,22 @@ gst_rtsp_session_pool_init (GstRTSPSessionPool * pool)
priv->max_sessions = DEFAULT_MAX_SESSIONS; priv->max_sessions = DEFAULT_MAX_SESSIONS;
} }
static GstRTSPFilterResult
remove_sessions_func (GstRTSPSessionPool * pool, GstRTSPSession * session,
gpointer user_data)
{
return GST_RTSP_FILTER_REMOVE;
}
static void static void
gst_rtsp_session_pool_finalize (GObject * object) gst_rtsp_session_pool_finalize (GObject * object)
{ {
GstRTSPSessionPool *pool = GST_RTSP_SESSION_POOL (object); GstRTSPSessionPool *pool = GST_RTSP_SESSION_POOL (object);
GstRTSPSessionPoolPrivate *priv = pool->priv; GstRTSPSessionPoolPrivate *priv = pool->priv;
g_mutex_clear (&priv->lock); gst_rtsp_session_pool_filter (pool, remove_sessions_func, NULL);
g_hash_table_unref (priv->sessions); g_hash_table_unref (priv->sessions);
g_mutex_clear (&priv->lock);
G_OBJECT_CLASS (gst_rtsp_session_pool_parent_class)->finalize (object); G_OBJECT_CLASS (gst_rtsp_session_pool_parent_class)->finalize (object);
} }
@ -428,18 +450,38 @@ gst_rtsp_session_pool_remove (GstRTSPSessionPool * pool, GstRTSPSession * sess)
priv = pool->priv; priv = pool->priv;
g_mutex_lock (&priv->lock); g_mutex_lock (&priv->lock);
g_object_ref (sess);
found = found =
g_hash_table_remove (priv->sessions, g_hash_table_remove (priv->sessions,
gst_rtsp_session_get_sessionid (sess)); gst_rtsp_session_get_sessionid (sess));
if (found) {
g_signal_emit (pool, gst_rtsp_session_pool_signals[SIGNAL_SESSION_REMOVED],
0, sess);
}
g_object_unref (sess);
g_mutex_unlock (&priv->lock); g_mutex_unlock (&priv->lock);
return found; return found;
} }
static gboolean typedef struct
cleanup_func (gchar * sessionid, GstRTSPSession * sess, GTimeVal * now)
{ {
return gst_rtsp_session_is_expired (sess, now); GTimeVal now;
GstRTSPSessionPool *pool;
} CleanupData;
static gboolean
cleanup_func (gchar * sessionid, GstRTSPSession * sess, CleanupData * data)
{
gboolean expired;
expired = gst_rtsp_session_is_expired (sess, &data->now);
if (expired) {
GST_DEBUG ("session expired, emitting signal");
g_signal_emit (data->pool,
gst_rtsp_session_pool_signals[SIGNAL_SESSION_REMOVED], 0, sess);
}
return expired;
} }
/** /**
@ -456,18 +498,19 @@ gst_rtsp_session_pool_cleanup (GstRTSPSessionPool * pool)
{ {
GstRTSPSessionPoolPrivate *priv; GstRTSPSessionPoolPrivate *priv;
guint result; guint result;
GTimeVal now; CleanupData data;
g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), 0); g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), 0);
priv = pool->priv; priv = pool->priv;
g_get_current_time (&now); g_get_current_time (&data.now);
data.pool = pool;
g_mutex_lock (&priv->lock); g_mutex_lock (&priv->lock);
result = result =
g_hash_table_foreach_remove (priv->sessions, (GHRFunc) cleanup_func, g_hash_table_foreach_remove (priv->sessions, (GHRFunc) cleanup_func,
&now); &data);
g_mutex_unlock (&priv->lock); g_mutex_unlock (&priv->lock);
return result; return result;
@ -493,6 +536,8 @@ filter_func (gchar * sessionid, GstRTSPSession * sess, FilterData * data)
switch (res) { switch (res) {
case GST_RTSP_FILTER_REMOVE: case GST_RTSP_FILTER_REMOVE:
g_signal_emit (data->pool,
gst_rtsp_session_pool_signals[SIGNAL_SESSION_REMOVED], 0, sess);
return TRUE; return TRUE;
case GST_RTSP_FILTER_REF: case GST_RTSP_FILTER_REF:
/* keep ref */ /* keep ref */
@ -514,7 +559,8 @@ filter_func (gchar * sessionid, GstRTSPSession * sess, FilterData * data)
* what happens to the session. @func will be called with the session pool * what happens to the session. @func will be called with the session pool
* locked so no further actions on @pool can be performed from @func. * locked so no further actions on @pool can be performed from @func.
* *
* If @func returns #GST_RTSP_FILTER_REMOVE, the session will be removed from * If @func returns #GST_RTSP_FILTER_REMOVE, the session will be set to the
* expired state with gst_rtsp_session_set_expired() and removed from
* @pool. * @pool.
* *
* If @func returns #GST_RTSP_FILTER_KEEP, the session will remain in @pool. * If @func returns #GST_RTSP_FILTER_KEEP, the session will remain in @pool.

View file

@ -58,6 +58,7 @@ struct _GstRTSPSessionPool {
* @create_session_id: create a new random session id. Subclasses can create * @create_session_id: create a new random session id. Subclasses can create
* custom session ids and should not check if the session exists. * custom session ids and should not check if the session exists.
* @create_session: make a new session object. * @create_session: make a new session object.
* @session_removed: a session was removed from the pool
*/ */
struct _GstRTSPSessionPoolClass { struct _GstRTSPSessionPoolClass {
GObjectClass parent_class; GObjectClass parent_class;
@ -65,8 +66,12 @@ struct _GstRTSPSessionPoolClass {
gchar * (*create_session_id) (GstRTSPSessionPool *pool); gchar * (*create_session_id) (GstRTSPSessionPool *pool);
GstRTSPSession * (*create_session) (GstRTSPSessionPool *pool, const gchar *id); GstRTSPSession * (*create_session) (GstRTSPSessionPool *pool, const gchar *id);
/* signals */
void (*session_removed) (GstRTSPSessionPool *pool,
GstRTSPSession *session);
/*< private >*/ /*< private >*/
gpointer _gst_reserved[GST_PADDING_LARGE]; gpointer _gst_reserved[GST_PADDING_LARGE - 1];
}; };
/** /**