/**
 * 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;
  guint retry;

  g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), NULL);

  klass = GST_RTSP_SESSION_POOL_GET_CLASS (pool);

  retry = 0;
  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 session limit */
    if (pool->max_sessions > 0) {
      if (g_hash_table_size (pool->sessions) >= pool->max_sessions)
        goto too_many_sessions;
    }
    /* check if the sessionid existed */
    result = g_hash_table_lookup (pool->sessions, id);
    if (result) {
      /* found, retry with a different session id */
      result = NULL;
      retry++;
      if (retry > 100)
        goto collision;
    } 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:
  {
    GST_WARNING ("no create_session_id vmethod in GstRTSPSessionPool %p", pool);
    return NULL;
  }
no_session:
  {
    GST_WARNING ("can't create session id with GstRTSPSessionPool %p", pool);
    return NULL;
  }
collision:
  {
    GST_WARNING ("can't find unique sessionid for GstRTSPSessionPool %p", pool);
    g_mutex_unlock (&pool->lock);
    g_free (id);
    return NULL;
  }
too_many_sessions:
  {
    GST_WARNING ("session pool reached max sessions of %d", pool->max_sessions);
    g_mutex_unlock (&pool->lock);
    g_free (id);
    return NULL;
  }
}
static GstRTSPSession *
create_session (GstRTSPSessionPool * pool, const gchar * id)
{
  return gst_rtsp_session_new (id);
}