time_t last_used; //!< Last time the connection was
//!< reserved.
- uint64_t num_uses; //!< Number of times the connection
+ uint32_t num_uses; //!< Number of times the connection
//!< has been reserved.
- int in_use; //!< Whether the connection is currently
- //!< reserved.
uint64_t number; //!< Unique ID assigned when the
//!< connection is created, these will
//!< monotonically increase over the
//!< lifetime of the connection pool.
void *connection; //!< Pointer to whatever the module
//!< uses for a connection handle.
+ bool in_use; //!< Whether the connection is currently
+ //!< reserved.
#ifdef PTHREAD_DEBUG
pthread_t pthread_id; //!< When 'in_use == true'
#endif
* @see fr_connection
*/
struct fr_connection_pool_t {
- int start; //!< Number of initial connections
- int min; //!< Minimum number of concurrent
+ uint32_t start; //!< Number of initial connections
+ uint32_t min; //!< Minimum number of concurrent
//!< connections to keep open.
- int max; //!< Maximum number of concurrent
+ uint32_t max; //!< Maximum number of concurrent
//!< connections to allow.
- int spare; //!< Number of spare connections to try
- int retry_delay; //!< seconds to delay re-open
+ uint32_t spare; //!< Number of spare connections to try
+ uint32_t retry_delay; //!< seconds to delay re-open
//!< after a failed open.
- int cleanup_interval; //!< Initial timer for how
+ uint32_t cleanup_interval; //!< Initial timer for how
//!< often we sweep the pool
//!< for free connections.
//!< (0 is infinite).
uint64_t max_uses; //!< Maximum number of times a
//!< connection can be used before being
//!< closed.
- int lifetime; //!< How long a connection can be open
+ uint32_t lifetime; //!< How long a connection can be open
//!< before being closed (irrespective
//!< of whether it's idle or not).
- int idle_timeout; //!< How long a connection can be idle
+ uint32_t idle_timeout; //!< How long a connection can be idle
//!< before being closed.
bool trigger; //!< If true execute connection triggers
uint64_t count; //!< Number of connections spawned over
//!< the lifetime of the pool.
- int num; //!< Number of connections in the pool.
+ uint32_t num; //!< Number of connections in the pool.
int active; //!< Number of currently reserved
//!< connections.
#endif
static const CONF_PARSER connection_config[] = {
- { "start", PW_TYPE_INTEGER, offsetof(fr_connection_pool_t, start),
- 0, "5" },
- { "min", PW_TYPE_INTEGER, offsetof(fr_connection_pool_t, min),
- 0, "5" },
- { "max", PW_TYPE_INTEGER, offsetof(fr_connection_pool_t, max),
- 0, "10" },
- { "spare", PW_TYPE_INTEGER, offsetof(fr_connection_pool_t, spare),
- 0, "3" },
- { "uses", PW_TYPE_INTEGER, offsetof(fr_connection_pool_t, max_uses),
- 0, "0" },
- { "lifetime", PW_TYPE_INTEGER, offsetof(fr_connection_pool_t, lifetime),
- 0, "0" },
- { "cleanup_delay", PW_TYPE_INTEGER, offsetof(fr_connection_pool_t, cleanup_interval),
- 0, NULL},
- { "cleanup_interval", PW_TYPE_INTEGER, offsetof(fr_connection_pool_t, cleanup_interval),
- 0, "30" },
- { "idle_timeout", PW_TYPE_INTEGER, offsetof(fr_connection_pool_t, idle_timeout),
- 0, "60" },
- { "retry_delay", PW_TYPE_INTEGER, offsetof(fr_connection_pool_t, retry_delay),
- 0, "1" },
- { "spread", PW_TYPE_BOOLEAN, offsetof(fr_connection_pool_t, spread),
- 0, "no" },
+ { "start", FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, start), "5" },
+ { "min", FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, min), "5" },
+ { "max", FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, max), "10" },
+ { "spare", FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, spare), "3" },
+ { "uses", FR_CONF_OFFSET(PW_TYPE_INTEGER64, fr_connection_pool_t, max_uses), "0" },
+ { "lifetime", FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, lifetime), "0" },
+ { "cleanup_delay", FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, cleanup_interval), NULL},
+ { "cleanup_interval", FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, cleanup_interval), "30" },
+ { "idle_timeout", FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, idle_timeout), "60" },
+ { "retry_delay", FR_CONF_OFFSET(PW_TYPE_INTEGER, fr_connection_pool_t, retry_delay), "1" },
+ { "spread", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, fr_connection_pool_t, spread), "no" },
{ NULL, -1, 0, NULL, NULL }
};
pthread_mutex_unlock(&pool->mutex);
- if (complain) {
- ERROR("%s: Last connection attempt failed, "
- "waiting %d seconds before retrying",
+ if (!RATE_LIMIT_ENABLED || complain) {
+ ERROR("%s: Last connection attempt failed, waiting %d seconds before retrying",
pool->log_prefix, pool->retry_delay);
}
fr_connection_delete_t d,
char const *prefix)
{
- int i;
+ uint32_t i;
fr_connection_pool_t *pool;
fr_connection_t *this;
CONF_SECTION *modules;
cs = cf_section_sub_find(parent, "pool");
if (!cs) cs = cf_section_sub_find(parent, "limit");
- if (cs) {
- pool = talloc_zero(cs, fr_connection_pool_t);
- } else {
- pool = talloc_zero(parent, fr_connection_pool_t);
- }
+ /*
+ * Pool is allocated in the NULL context as
+ * threads are likely to allocate memory
+ * beneath the pool.
+ */
+ pool = talloc_zero(NULL, fr_connection_pool_t);
if (!pool) return NULL;
+ /*
+ * Ensure the pool is freed at the same time
+ * as its parent.
+ */
+ if (fr_link_talloc_ctx_free(cs ? cs : parent, pool) < 0) {
+ talloc_free(pool);
+ return NULL;
+ }
+
pool->cs = cs;
pool->ctx = ctx;
pool->create = c;
pool->idle_timeout = 0;
}
- if (pool->cleanup_interval < 0) {
- pool->cleanup_interval = 30;
- }
-
if ((pool->idle_timeout > 0) && (pool->cleanup_interval > pool->idle_timeout)) {
pool->cleanup_interval = pool->idle_timeout;
}
*/
static int fr_connection_pool_check(fr_connection_pool_t *pool)
{
- int spawn, idle, extra;
+ uint32_t spawn, idle, extra;
time_t now = time(NULL);
fr_connection_t *this, *next;
pthread_mutex_unlock(&pool->mutex);
- if (complain) {
+ if (!RATE_LIMIT_ENABLED || complain) {
ERROR("%s: No connections available and at max connection limit", pool->log_prefix);
}
return fr_connection_get_internal(pool, true);
}
+/** Get the number of connections currently in the pool
+ *
+ * @param pool to count connections for.
+ * @return the number of connections in the pool
+ */
+int fr_connection_get_num(fr_connection_pool_t *pool)
+{
+ return pool->num;
+}
/** Release a connection
*