mirror of https://github.com/yandex/odyssey.git
174 lines
6.4 KiB
C
174 lines
6.4 KiB
C
#ifndef ODYSSEY_SERVER_POOL_H
|
|
#define ODYSSEY_SERVER_POOL_H
|
|
|
|
/*
|
|
* Odyssey.
|
|
*
|
|
* Scalable PostgreSQL connection pooler.
|
|
*/
|
|
|
|
typedef struct od_server_pool od_server_pool_t;
|
|
|
|
typedef int (*od_server_pool_cb_t)(od_server_t *, void **);
|
|
|
|
struct od_server_pool {
|
|
od_list_t active;
|
|
od_list_t idle;
|
|
int count_active;
|
|
int count_idle;
|
|
};
|
|
|
|
static inline void od_server_pool_init(od_server_pool_t *pool)
|
|
{
|
|
pool->count_active = 0;
|
|
pool->count_idle = 0;
|
|
od_list_init(&pool->idle);
|
|
od_list_init(&pool->active);
|
|
}
|
|
|
|
#define OD_SERVER_POOL_FREE_DECLARE(name, type, server_free_cb) \
|
|
static inline void od_##name##_server_pool_free( \
|
|
od_server_pool_t *pool) \
|
|
{ \
|
|
type *server; \
|
|
od_list_t *i, *n; \
|
|
\
|
|
od_list_foreach_safe(&pool->idle, i, n) \
|
|
{ \
|
|
server = od_container_of(i, type, link); \
|
|
server_free_cb(server); \
|
|
} \
|
|
\
|
|
od_list_foreach_safe(&pool->active, i, n) \
|
|
{ \
|
|
server = od_container_of(i, type, link); \
|
|
server_free_cb(server); \
|
|
} \
|
|
}
|
|
|
|
OD_SERVER_POOL_FREE_DECLARE(pg, od_server_t, od_server_free)
|
|
|
|
#ifdef LDAP_FOUND
|
|
OD_SERVER_POOL_FREE_DECLARE(ldap, od_ldap_server_t, od_ldap_server_free)
|
|
#endif
|
|
|
|
#define OD_SERVER_POOL_SET_DECLARE(name, type) \
|
|
static inline void od_##name##_server_pool_set( \
|
|
od_server_pool_t *pool, type *server, od_server_state_t state) \
|
|
{ \
|
|
if (server->state == state) \
|
|
return; \
|
|
switch (server->state) { \
|
|
case OD_SERVER_UNDEF: \
|
|
break; \
|
|
case OD_SERVER_IDLE: \
|
|
pool->count_idle--; \
|
|
break; \
|
|
case OD_SERVER_ACTIVE: \
|
|
pool->count_active--; \
|
|
break; \
|
|
} \
|
|
\
|
|
od_list_t *target = NULL; \
|
|
switch (state) { \
|
|
case OD_SERVER_UNDEF: \
|
|
break; \
|
|
case OD_SERVER_IDLE: \
|
|
target = &pool->idle; \
|
|
pool->count_idle++; \
|
|
break; \
|
|
case OD_SERVER_ACTIVE: \
|
|
target = &pool->active; \
|
|
pool->count_active++; \
|
|
break; \
|
|
} \
|
|
\
|
|
od_list_unlink(&server->link); \
|
|
od_list_init(&server->link); \
|
|
if (target) { \
|
|
od_list_push(target, &server->link); \
|
|
} \
|
|
server->state = state; \
|
|
}
|
|
|
|
OD_SERVER_POOL_SET_DECLARE(pg, od_server_t)
|
|
|
|
#ifdef LDAP_FOUND
|
|
OD_SERVER_POOL_SET_DECLARE(ldap, od_ldap_server_t)
|
|
#endif
|
|
|
|
#define OD_SERVER_POOL_NEXT_DECLARE(name, type) \
|
|
static inline type *od_##name##_server_pool_next( \
|
|
od_server_pool_t *pool, od_server_state_t state) \
|
|
{ \
|
|
int target_count = 0; \
|
|
od_list_t *target = NULL; \
|
|
switch (state) { \
|
|
case OD_SERVER_IDLE: \
|
|
target_count = pool->count_idle; \
|
|
target = &pool->idle; \
|
|
break; \
|
|
case OD_SERVER_ACTIVE: \
|
|
target_count = pool->count_active; \
|
|
target = &pool->active; \
|
|
break; \
|
|
case OD_SERVER_UNDEF: \
|
|
assert(0); \
|
|
break; \
|
|
} \
|
|
if (target_count == 0) \
|
|
return NULL; \
|
|
type *server; \
|
|
server = od_container_of(target->next, type, link); \
|
|
return server; \
|
|
}
|
|
|
|
OD_SERVER_POOL_NEXT_DECLARE(pg, od_server_t)
|
|
|
|
#ifdef LDAP_FOUND
|
|
OD_SERVER_POOL_NEXT_DECLARE(ldap, od_ldap_server_t)
|
|
#endif
|
|
|
|
static inline od_server_t *od_server_pool_foreach(od_server_pool_t *pool,
|
|
od_server_state_t state,
|
|
od_server_pool_cb_t callback,
|
|
void **argv)
|
|
{
|
|
od_list_t *target = NULL;
|
|
switch (state) {
|
|
case OD_SERVER_IDLE:
|
|
target = &pool->idle;
|
|
break;
|
|
case OD_SERVER_ACTIVE:
|
|
target = &pool->active;
|
|
break;
|
|
case OD_SERVER_UNDEF:
|
|
assert(0);
|
|
break;
|
|
}
|
|
od_server_t *server;
|
|
od_list_t *i, *n;
|
|
od_list_foreach_safe(target, i, n)
|
|
{
|
|
server = od_container_of(i, od_server_t, link);
|
|
int rc;
|
|
rc = callback(server, argv);
|
|
if (rc) {
|
|
return server;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static inline int od_server_pool_active(od_server_pool_t *pool)
|
|
{
|
|
return pool->count_active;
|
|
}
|
|
|
|
static inline int od_server_pool_total(od_server_pool_t *pool)
|
|
{
|
|
return pool->count_active + pool->count_idle;
|
|
}
|
|
|
|
#endif /* ODYSSEY_SERVER_POOL_H */
|