+ priv = pool->priv;
+
+ result = NULL;
+ if (func)
+ visited = g_hash_table_new_full (NULL, NULL, g_object_unref, NULL);
+
+ g_mutex_lock (&priv->lock);
+restart:
+ g_hash_table_iter_init (&iter, priv->sessions);
+ cookie = priv->sessions_cookie;
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ GstRTSPSession *session = value;
+ GstRTSPFilterResult res;
+ gboolean changed;
+
+ if (func) {
+ /* only visit each session once */
+ if (g_hash_table_contains (visited, session))
+ continue;
+
+ g_hash_table_add (visited, g_object_ref (session));
+ g_mutex_unlock (&priv->lock);
+
+ res = func (pool, session, user_data);
+
+ g_mutex_lock (&priv->lock);
+ } else
+ res = GST_RTSP_FILTER_REF;
+
+ changed = (cookie != priv->sessions_cookie);
+
+ switch (res) {
+ case GST_RTSP_FILTER_REMOVE:
+ {
+ gboolean removed = TRUE;
+
+ if (changed)
+ /* something changed, check if we still have the session */
+ removed = g_hash_table_remove (priv->sessions, key);
+ else
+ g_hash_table_iter_remove (&iter);
+
+ 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));
+ break;
+ case GST_RTSP_FILTER_KEEP:
+ default:
+ break;
+ }
+ if (changed)
+ goto restart;
+ }
+ g_mutex_unlock (&priv->lock);