summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2014-07-10 12:20:15 +0200
committerWim Taymans <wtaymans@redhat.com>2014-07-10 12:20:15 +0200
commit301585b30f7d6a604252df96a999d6e2435b1fab (patch)
tree68c684dad6a60e7af7a37aa0b48422686c57ae17
parent945c93fde09b461d4b810846e2a9443f915e6507 (diff)
session-pool: signal session-removed outside of the lock
Release the lock before emiting the session-removed signal.
-rw-r--r--gst/rtsp-server/rtsp-session-pool.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/gst/rtsp-server/rtsp-session-pool.c b/gst/rtsp-server/rtsp-session-pool.c
index 7699196..fad5288 100644
--- a/gst/rtsp-server/rtsp-session-pool.c
+++ b/gst/rtsp-server/rtsp-session-pool.c
@@ -456,13 +456,15 @@ gst_rtsp_session_pool_remove (GstRTSPSessionPool * pool, GstRTSPSession * sess)
found =
g_hash_table_remove (priv->sessions,
gst_rtsp_session_get_sessionid (sess));
- if (found) {
+ if (found)
priv->sessions_cookie++;
+ g_mutex_unlock (&priv->lock);
+
+ 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);
return found;
}
@@ -471,6 +473,7 @@ typedef struct
{
GTimeVal now;
GstRTSPSessionPool *pool;
+ GList *removed;
} CleanupData;
static gboolean
@@ -480,9 +483,8 @@ cleanup_func (gchar * sessionid, GstRTSPSession * sess, CleanupData * data)
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);
+ GST_DEBUG ("session expired");
+ data->removed = g_list_prepend (data->removed, g_object_ref (sess));
}
return expired;
}
@@ -502,6 +504,7 @@ gst_rtsp_session_pool_cleanup (GstRTSPSessionPool * pool)
GstRTSPSessionPoolPrivate *priv;
guint result;
CleanupData data;
+ GList *walk;
g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), 0);
@@ -509,6 +512,7 @@ gst_rtsp_session_pool_cleanup (GstRTSPSessionPool * pool)
g_get_current_time (&data.now);
data.pool = pool;
+ data.removed = NULL;
g_mutex_lock (&priv->lock);
result =
@@ -518,6 +522,16 @@ gst_rtsp_session_pool_cleanup (GstRTSPSessionPool * pool)
priv->sessions_cookie++;
g_mutex_unlock (&priv->lock);
+ for (walk = data.removed; walk; walk = walk->next) {
+ GstRTSPSession *sess = walk->data;
+
+ g_signal_emit (pool,
+ gst_rtsp_session_pool_signals[SIGNAL_SESSION_REMOVED], 0, sess);
+
+ g_object_unref (sess);
+ }
+ g_list_free (data.removed);
+
return result;
}
@@ -593,15 +607,31 @@ restart:
switch (res) {
case GST_RTSP_FILTER_REMOVE:
- g_signal_emit (pool,
- gst_rtsp_session_pool_signals[SIGNAL_SESSION_REMOVED], 0, session);
+ {
+ gboolean removed = TRUE;
if (changed)
- g_hash_table_remove (priv->sessions, key);
+ /* something changed, check if we still have the session */
+ removed = g_hash_table_remove (priv->sessions, key);
else
g_hash_table_iter_remove (&iter);
- cookie = ++priv->sessions_cookie;
+
+ if (removed) {
+ /* if we managed to remove the session, update the cookie and
+ * signal */
+ cookie = ++priv->sessions_cookie;
+ g_mutex_unlock (&priv->lock);
+
+ g_signal_emit (pool,
+ gst_rtsp_session_pool_signals[SIGNAL_SESSION_REMOVED], 0,
+ session);
+
+ g_mutex_lock (&priv->lock);
+ /* cookie could have changed again, make sure we restart */
+ changed |= (cookie != priv->sessions_cookie);
+ }
break;
+ }
case GST_RTSP_FILTER_REF:
/* keep ref */
result = g_list_prepend (result, g_object_ref (session));