varcache.c aatree.c hash.c slab.c
HDRS = client.h loader.h objects.h pooler.h proto.h sbuf.h server.h util.h \
admin.h stats.h takeover.h md5.h janitor.h pktbuf.h system.h bouncer.h \
- list.h mbuf.h varcache.h aatree.h hash.h slab.h iobuf.h
+ mbuf.h varcache.h aatree.h hash.h slab.h iobuf.h
# data & dirs to include in tgz
DOCS = doc/overview.txt doc/usage.txt doc/config.txt doc/todo.txt
#include "system.h"
#include <usual/time.h>
+#include <usual/list.h>
+#include <usual/statlist.h>
#include <event.h>
#include "aatree.h"
#include "hash.h"
#include "util.h"
-#include "list.h"
#include "mbuf.h"
#include "iobuf.h"
#include "sbuf.h"
* ->newer_stats = ->stats
*/
struct PgPool {
- List head; /* entry in global pool_list */
- List map_head; /* entry in user->pool_list */
+ struct List head; /* entry in global pool_list */
+ struct List map_head; /* entry in user->pool_list */
PgDatabase *db; /* corresponging database */
PgUser *user; /* user logged in as */
- StatList active_client_list; /* waiting events logged in clients */
- StatList waiting_client_list; /* client waits for a server to be available */
- StatList cancel_req_list; /* closed client connections with server key */
+ struct StatList active_client_list; /* waiting events logged in clients */
+ struct StatList waiting_client_list; /* client waits for a server to be available */
+ struct StatList cancel_req_list; /* closed client connections with server key */
- StatList active_server_list; /* servers linked with clients */
- StatList idle_server_list; /* servers ready to be linked with clients */
- StatList used_server_list; /* server just unlinked from clients */
- StatList tested_server_list; /* server in testing process */
- StatList new_server_list; /* servers in login phase */
+ struct StatList active_server_list; /* servers linked with clients */
+ struct StatList idle_server_list; /* servers ready to be linked with clients */
+ struct StatList used_server_list; /* server just unlinked from clients */
+ struct StatList tested_server_list; /* server in testing process */
+ struct StatList new_server_list; /* servers in login phase */
PgStats stats;
PgStats newer_stats;
* whis user has logged in.
*/
struct PgUser {
- List head; /* used to attach user to list */
- List pool_list; /* list of pools where pool->user == this user */
+ struct List head; /* used to attach user to list */
+ struct List pool_list; /* list of pools where pool->user == this user */
Node tree_node; /* used to attach user to tree */
char name[MAX_USERNAME];
char passwd[MAX_PASSWORD];
* A database entry from config.
*/
struct PgDatabase {
- List head;
+ struct List head;
char name[MAX_DBNAME]; /* db name for clients */
bool db_paused; /* PAUSE <db>; was issued */
* ->state corresponds to various lists the struct can be at.
*/
struct PgSocket {
- List head; /* list header */
+ struct List head; /* list header */
PgSocket *link; /* the dest of packets */
PgPool *pool; /* parent pool, if NULL not yet assigned */
extern usec_t g_suspend_start;
static inline PgSocket * _MUSTCHECK
-pop_socket(StatList *slist)
+pop_socket(struct StatList *slist)
{
- List *item = statlist_pop(slist);
+ struct List *item = statlist_pop(slist);
if (item == NULL)
return NULL;
return container_of(item, PgSocket, head);
}
static inline PgSocket *
-first_socket(StatList *slist)
+first_socket(struct StatList *slist)
{
if (statlist_empty(slist))
return NULL;
+++ /dev/null
-/*
- * PgBouncer - Lightweight connection pooler for PostgreSQL.
- *
- * Copyright (c) 2007-2009 Marko Kreen, Skype Technologies OÜ
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Circular doubly linked list implementation.
- *
- * Basic idea from <linux/list.h>.
- *
- * <sys/queue.h> seemed usable, but overcomplicated.
- */
-
-#ifndef __LIST_H_
-#define __LIST_H_
-
-/* turn on slow checking */
-/* #define LIST_DEBUG */
-
-/* give offset of a field inside struct */
-#ifndef offsetof
-#define offsetof(type, field) ((unsigned long)&(((type *)0)->field))
-#endif
-
-/* given pointer to field inside struct, return pointer to struct */
-#ifndef container_of
-#define container_of(ptr, type, field) ((type *)((char *)(ptr) - offsetof(type, field)))
-#endif
-
-/* list type */
-typedef struct List List;
-struct List {
- List *next;
- List *prev;
-};
-
-#define LIST(var) List var = { &var, &var }
-
-/* initialize struct */
-static inline void list_init(List *list)
-{
- list->next = list->prev = list;
-}
-
-/* is list empty? */
-static inline bool list_empty(const List *list)
-{
- return list->next == list;
-}
-
-/* add item to the start of the list */
-static inline List *list_prepend(List *item, List *list)
-{
- Assert(list_empty(item));
-
- item->next = list->next;
- item->prev = list;
- list->next->prev = item;
- list->next = item;
- return item;
-}
-
-/* add item to the end of the list */
-static inline List *list_append(List *item, List *list)
-{
- Assert(list_empty(item));
-
- item->next = list;
- item->prev = list->prev;
- list->prev->next = item;
- list->prev = item;
- return item;
-}
-
-/* remove item from list */
-static inline List *list_del(List *item)
-{
- item->prev->next = item->next;
- item->next->prev = item->prev;
- item->next = item->prev = item;
- return item;
-}
-
-/* remove first from list and return */
-static inline List *list_pop(List *list)
-{
- if (list_empty(list))
- return NULL;
- return list_del(list->next);
-}
-
-/* remove first from list and return */
-static inline List *list_first(const List *list)
-{
- if (list_empty(list))
- return NULL;
- return list->next;
-}
-
-/* put all elems in one list in the start of another list */
-static inline void list_prepend_list(List *src, List *dst)
-{
- if (list_empty(src))
- return;
- src->next->prev = dst;
- src->prev->next = dst->next;
- dst->next->prev = src->prev;
- dst->next = src->next;
-
- src->next = src->prev = src;
-}
-
-/* put all elems in one list in the end of another list */
-static inline void list_append_list(List *src, List *dst)
-{
- if (list_empty(src))
- return;
- src->next->prev = dst->prev;
- src->prev->next = dst;
- dst->prev->next = src->next;
- dst->prev = src->prev;
-
- src->next = src->prev = src;
-}
-
-/* remove first elem from list and return with casting */
-#define list_pop_type(list, typ, field) \
- (list_empty(list) ? NULL \
- : container_of(list_del((list)->next), typ, field))
-
-/* loop over list */
-#define list_for_each(item, list) \
- for ((item) = (list)->next; \
- (item) != (list); \
- (item) = (item)->next)
-
-/* loop over list and allow removing item */
-#define list_for_each_safe(item, list, tmp) \
- for ((item) = (list)->next, (tmp) = (list)->next->next; \
- (item) != (list); \
- (item) = (tmp), (tmp) = (tmp)->next)
-
-static inline bool item_in_list(const List *item, const List *list)
-{
- List *tmp;
- list_for_each(tmp, list)
- if (tmp == item)
- return 1;
- return 0;
-}
-
-
-/*
- * wrapper for List that keeps track of number of items
- */
-
-typedef struct StatList StatList;
-struct StatList {
- List head;
- int cur_count;
-#ifdef LIST_DEBUG
- const char *name;
-#endif
-};
-
-#ifdef LIST_DEBUG
-#define STATLIST(var) StatList var = { {&var.head, &var.head}, 0, #var }
-#else
-#define STATLIST(var) StatList var = { {&var.head, &var.head}, 0 }
-#endif
-
-static inline void statlist_inc_count(StatList *list, int val)
-{
- list->cur_count += val;
-}
-
-static inline void statlist_prepend(List *item, StatList *list)
-{
- list_prepend(item, &list->head);
- statlist_inc_count(list, 1);
-}
-
-static inline void statlist_append(List *item, StatList *list)
-{
- list_append(item, &list->head);
- statlist_inc_count(list, 1);
-}
-
-static inline void statlist_put_before(List *item, StatList *list, List *pos)
-{
- list_append(item, pos);
- statlist_inc_count(list, 1);
-}
-
-static inline void statlist_remove(List *item, StatList *list)
-{
-#ifdef LIST_DEBUG
- /* sanity check */
- if (!item_in_list(item, &list->head))
- fatal("item in wrong list, expected: %s", list->name);
-#endif
-
- list_del(item);
- list->cur_count--;
-
- Assert(list->cur_count >= 0);
-}
-
-static inline void statlist_init(StatList *list, const char *name)
-{
- list_init(&list->head);
- list->cur_count = 0;
-#ifdef LIST_DEBUG
- list->name = name;
-#endif
-}
-
-static inline int statlist_count(const StatList *list)
-{
- Assert(list->cur_count > 0 || list_empty(&list->head));
- return list->cur_count;
-}
-
-static inline List *statlist_pop(StatList *list)
-{
- List *item = list_pop(&list->head);
-
- if (item)
- list->cur_count--;
-
- Assert(list->cur_count >= 0);
-
- return item;
-}
-
-static inline void statlist_prepend_list(StatList *src, StatList *dst)
-{
- list_prepend_list(&src->head, &dst->head);
- statlist_inc_count(dst, src->cur_count);
- src->cur_count = 0;
-}
-
-static inline void statlist_append_list(StatList *src, StatList *dst)
-{
- list_append_list(&src->head, &dst->head);
- statlist_inc_count(dst, src->cur_count);
- src->cur_count = 0;
-}
-
-static inline List *statlist_first(const StatList *list)
-{
- return list_first(&list->head);
-}
-
-static inline bool statlist_empty(const StatList *list)
-{
- return list_empty(&list->head);
-}
-
-#define statlist_for_each(item, list) list_for_each(item, &((list)->head))
-#define statlist_for_each_safe(item, list, tmp) list_for_each_safe(item, &((list)->head), tmp)
-
-#endif /* __LIST_H_ */
-
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-extern StatList user_list;
+extern struct StatList user_list;
extern Tree user_tree;
-extern StatList pool_list;
-extern StatList database_list;
-extern StatList autodatabase_idle_list;
-extern StatList login_client_list;
+extern struct StatList pool_list;
+extern struct StatList database_list;
+extern struct StatList autodatabase_idle_list;
+extern struct StatList login_client_list;
extern ObjectCache *client_cache;
extern ObjectCache *server_cache;
extern ObjectCache *db_cache;
void stats_setup(void);
-bool admin_database_stats(PgSocket *client, StatList *pool_list) _MUSTCHECK;
-bool show_stat_totals(PgSocket *client, StatList *pool_list) _MUSTCHECK;
+bool admin_database_stats(PgSocket *client, struct StatList *pool_list) _MUSTCHECK;
+bool show_stat_totals(PgSocket *client, struct StatList *pool_list) _MUSTCHECK;
static int count_paused_databases(void)
{
- List *item;
+ struct List *item;
PgDatabase *db;
int cnt = 0;
static int count_db_active(PgDatabase *db)
{
- List *item;
+ struct List *item;
PgPool *pool;
int cnt = 0;
return res;
}
-static bool show_fds_from_list(PgSocket *admin, StatList *list)
+static bool show_fds_from_list(PgSocket *admin, struct StatList *list)
{
- List *item;
+ struct List *item;
PgSocket *sk;
bool res = true;
*/
static bool admin_show_fds(PgSocket *admin, const char *arg)
{
- List *item;
+ struct List *item;
PgPool *pool;
bool res;
static bool admin_show_databases(PgSocket *admin, const char *arg)
{
PgDatabase *db;
- List *item;
+ struct List *item;
char *host;
const char *f_user;
PktBuf *buf;
static bool admin_show_users(PgSocket *admin, const char *arg)
{
PgUser *user;
- List *item;
+ struct List *item;
PktBuf *buf = pktbuf_dynamic(256);
if (!buf) {
admin_error(admin, "no mem");
}
/* Helper for SHOW CLIENTS */
-static void show_socket_list(PktBuf *buf, StatList *list, const char *state, bool debug)
+static void show_socket_list(PktBuf *buf, struct StatList *list, const char *state, bool debug)
{
- List *item;
+ struct List *item;
PgSocket *sk;
statlist_for_each(item, list) {
/* Command: SHOW CLIENTS */
static bool admin_show_clients(PgSocket *admin, const char *arg)
{
- List *item;
+ struct List *item;
PgPool *pool;
PktBuf *buf = pktbuf_dynamic(256);
/* Command: SHOW SERVERS */
static bool admin_show_servers(PgSocket *admin, const char *arg)
{
- List *item;
+ struct List *item;
PgPool *pool;
PktBuf *buf;
/* Command: SHOW SOCKETS */
static bool admin_show_sockets(PgSocket *admin, const char *arg)
{
- List *item;
+ struct List *item;
PgPool *pool;
PktBuf *buf;
return true;
}
-static void show_active_socket_list(PktBuf *buf, StatList *list, const char *state)
+static void show_active_socket_list(PktBuf *buf, struct StatList *list, const char *state)
{
- List *item;
+ struct List *item;
statlist_for_each(item, list) {
PgSocket *sk = container_of(item, PgSocket, head);
if (!sbuf_is_empty(&sk->sbuf))
/* Command: SHOW ACTIVE_SOCKETS */
static bool admin_show_active_sockets(PgSocket *admin, const char *arg)
{
- List *item;
+ struct List *item;
PgPool *pool;
PktBuf *buf;
/* Command: SHOW POOLS */
static bool admin_show_pools(PgSocket *admin, const char *arg)
{
- List *item;
+ struct List *item;
PgPool *pool;
PktBuf *buf;
PgSocket *waiter;
void admin_pause_done(void)
{
- List *item, *tmp;
+ struct List *item, *tmp;
PgSocket *admin;
bool res;
static struct event full_maint_ev;
/* close all sockets in server list */
-static void close_server_list(StatList *sk_list, const char *reason)
+static void close_server_list(struct StatList *sk_list, const char *reason)
{
- List *item, *tmp;
+ struct List *item, *tmp;
PgSocket *server;
statlist_for_each_safe(item, sk_list, tmp) {
}
}
-static void close_client_list(StatList *sk_list, const char *reason)
+static void close_client_list(struct StatList *sk_list, const char *reason)
{
- List *item, *tmp;
+ struct List *item, *tmp;
PgSocket *client;
statlist_for_each_safe(item, sk_list, tmp) {
}
/* suspend all sockets in socket list */
-static int suspend_socket_list(StatList *list, bool force_suspend)
+static int suspend_socket_list(struct StatList *list, bool force_suspend)
{
- List *item, *tmp;
+ struct List *item, *tmp;
PgSocket *sk;
int active = 0;
}
/* resume all suspended sockets in socket list */
-static void resume_socket_list(StatList *list)
+static void resume_socket_list(struct StatList *list)
{
- List *item, *tmp;
+ struct List *item, *tmp;
PgSocket *sk;
statlist_for_each_safe(item, list, tmp) {
/* resume all suspended sockets in all pools */
static void resume_sockets(void)
{
- List *item;
+ struct List *item;
PgPool *pool;
statlist_for_each(item, &pool_list) {
*/
static void per_loop_activate(PgPool *pool)
{
- List *item, *tmp;
+ struct List *item, *tmp;
PgSocket *client;
/* see if any server have been freed */
*/
void per_loop_maint(void)
{
- List *item;
+ struct List *item;
PgPool *pool;
int active = 0;
int partial_pause = 0;
/* maintaining clients in pool */
static void pool_client_maint(PgPool *pool)
{
- List *item, *tmp;
+ struct List *item, *tmp;
usec_t now = get_cached_time();
PgSocket *client;
usec_t age;
}
}
-static void check_unused_servers(PgPool *pool, StatList *slist, bool idle_test)
+static void check_unused_servers(PgPool *pool, struct StatList *slist, bool idle_test)
{
usec_t now = get_cached_time();
- List *item, *tmp;
+ struct List *item, *tmp;
usec_t idle, age;
PgSocket *server;
usec_t lifetime_kill_gap = 0;
/* maintain servers in a pool */
static void pool_server_maint(PgPool *pool)
{
- List *item, *tmp;
+ struct List *item, *tmp;
usec_t age, now = get_cached_time();
PgSocket *server;
static void cleanup_client_logins(void)
{
- List *item, *tmp;
+ struct List *item, *tmp;
PgSocket *client;
usec_t age;
usec_t now = get_cached_time();
static void kill_database(PgDatabase *db);
static void cleanup_inactive_autodatabases(void)
{
- List *item, *tmp;
+ struct List *item, *tmp;
PgDatabase *db;
usec_t age;
usec_t now = get_cached_time();
/* full-scale maintenance, done only occasionally */
static void do_full_maint(int sock, short flags, void *arg)
{
- List *item, *tmp;
+ struct List *item, *tmp;
PgPool *pool;
/*
if (pool->db->db_auto && pool->db->inactive_time == 0 &&
pool_client_count(pool) == 0 && pool_server_count(pool) == 0 ) {
pool->db->inactive_time = get_cached_time();
- statlist_remove(&pool->db->head, &database_list);
- statlist_append(&pool->db->head, &autodatabase_idle_list);
+ statlist_remove(&database_list, &pool->db->head);
+ statlist_append(&autodatabase_idle_list, &pool->db->head);
}
}
close_server_list(&pool->new_server_list, reason);
list_del(&pool->map_head);
- statlist_remove(&pool->head, &pool_list);
+ statlist_remove(&pool_list, &pool->head);
obj_free(pool_cache, pool);
}
static void kill_database(PgDatabase *db)
{
PgPool *pool;
- List *item, *tmp;
+ struct List *item, *tmp;
log_warning("dropping database '%s' as it does not exist anymore or inactive auto-database", db->name);
if (db->connect_query)
free((void *)db->connect_query);
if (db->inactive_time)
- statlist_remove(&db->head, &autodatabase_idle_list);
+ statlist_remove(&autodatabase_idle_list, &db->head);
else
- statlist_remove(&db->head, &database_list);
+ statlist_remove(&database_list, &db->head);
obj_free(db_cache, db);
}
there's need for review */
void config_postprocess(void)
{
- List *item, *tmp;
+ struct List *item, *tmp;
PgDatabase *db;
statlist_for_each_safe(item, &database_list, tmp) {
static void disable_users(void)
{
PgUser *user;
- List *item;
+ struct List *item;
statlist_for_each(item, &user_list) {
user = container_of(item, PgUser, head);
static void set_dbs_dead(bool flag)
{
- List *item;
+ struct List *item;
PgDatabase *db;
statlist_for_each(item, &database_list) {
int total_users = statlist_count(&user_list);
int fd_count;
int err;
- List *item;
+ struct List *item;
PgDatabase *db;
log_noise("event: %d, SBuf: %d, PgSocket: %d, IOBuf: %d",
case CL_FREE:
break;
case CL_JUSTFREE:
- statlist_remove(&client->head, &justfree_client_list);
+ statlist_remove(&justfree_client_list, &client->head);
break;
case CL_LOGIN:
- statlist_remove(&client->head, &login_client_list);
+ statlist_remove(&login_client_list, &client->head);
break;
case CL_WAITING:
- statlist_remove(&client->head, &pool->waiting_client_list);
+ statlist_remove(&pool->waiting_client_list, &client->head);
break;
case CL_ACTIVE:
- statlist_remove(&client->head, &pool->active_client_list);
+ statlist_remove(&pool->active_client_list, &client->head);
break;
case CL_CANCEL:
- statlist_remove(&client->head, &pool->cancel_req_list);
+ statlist_remove(&pool->cancel_req_list, &client->head);
break;
default:
fatal("bad cur client state: %d", client->state);
obj_free(client_cache, client);
break;
case CL_JUSTFREE:
- statlist_append(&client->head, &justfree_client_list);
+ statlist_append(&justfree_client_list, &client->head);
break;
case CL_LOGIN:
- statlist_append(&client->head, &login_client_list);
+ statlist_append(&login_client_list, &client->head);
break;
case CL_WAITING:
- statlist_append(&client->head, &pool->waiting_client_list);
+ statlist_append(&pool->waiting_client_list, &client->head);
break;
case CL_ACTIVE:
- statlist_append(&client->head, &pool->active_client_list);
+ statlist_append(&pool->active_client_list, &client->head);
break;
case CL_CANCEL:
- statlist_append(&client->head, &pool->cancel_req_list);
+ statlist_append(&pool->cancel_req_list, &client->head);
break;
default:
fatal("bad new client state: %d", client->state);
case SV_FREE:
break;
case SV_JUSTFREE:
- statlist_remove(&server->head, &justfree_server_list);
+ statlist_remove(&justfree_server_list, &server->head);
break;
case SV_LOGIN:
- statlist_remove(&server->head, &pool->new_server_list);
+ statlist_remove(&pool->new_server_list, &server->head);
break;
case SV_USED:
- statlist_remove(&server->head, &pool->used_server_list);
+ statlist_remove(&pool->used_server_list, &server->head);
break;
case SV_TESTED:
- statlist_remove(&server->head, &pool->tested_server_list);
+ statlist_remove(&pool->tested_server_list, &server->head);
break;
case SV_IDLE:
- statlist_remove(&server->head, &pool->idle_server_list);
+ statlist_remove(&pool->idle_server_list, &server->head);
break;
case SV_ACTIVE:
- statlist_remove(&server->head, &pool->active_server_list);
+ statlist_remove(&pool->active_server_list, &server->head);
break;
default:
fatal("change_server_state: bad old server state: %d", server->state);
obj_free(server_cache, server);
break;
case SV_JUSTFREE:
- statlist_append(&server->head, &justfree_server_list);
+ statlist_append(&justfree_server_list, &server->head);
break;
case SV_LOGIN:
- statlist_append(&server->head, &pool->new_server_list);
+ statlist_append(&pool->new_server_list, &server->head);
break;
case SV_USED:
/* use LIFO */
- statlist_prepend(&server->head, &pool->used_server_list);
+ statlist_prepend(&pool->used_server_list, &server->head);
break;
case SV_TESTED:
- statlist_append(&server->head, &pool->tested_server_list);
+ statlist_append(&pool->tested_server_list, &server->head);
break;
case SV_IDLE:
if (server->close_needed || cf_server_round_robin)
/* try to avoid immediate usage then */
- statlist_append(&server->head, &pool->idle_server_list);
+ statlist_append(&pool->idle_server_list, &server->head);
else
/* otherwise use LIFO */
- statlist_prepend(&server->head, &pool->idle_server_list);
+ statlist_prepend(&pool->idle_server_list, &server->head);
break;
case SV_ACTIVE:
- statlist_append(&server->head, &pool->active_server_list);
+ statlist_append(&pool->active_server_list, &server->head);
break;
default:
fatal("bad server state");
}
/* compare pool names, for use with put_in_order */
-static int cmp_pool(List *i1, List *i2)
+static int cmp_pool(struct List *i1, struct List *i2)
{
PgPool *p1 = container_of(i1, PgPool, head);
PgPool *p2 = container_of(i2, PgPool, head);
}
/* compare user names, for use with put_in_order */
-static int cmp_user(List *i1, List *i2)
+static int cmp_user(struct List *i1, struct List *i2)
{
PgUser *u1 = container_of(i1, PgUser, head);
PgUser *u2 = container_of(i2, PgUser, head);
}
/* compare db names, for use with put_in_order */
-static int cmp_database(List *i1, List *i2)
+static int cmp_database(struct List *i1, struct List *i2)
{
PgDatabase *db1 = container_of(i1, PgDatabase, head);
PgDatabase *db2 = container_of(i2, PgDatabase, head);
}
/* put elem into list in correct pos */
-static void put_in_order(List *newitem, StatList *list, int (*cmpfn)(List *, List *))
+static void put_in_order(struct List *newitem, struct StatList *list,
+ int (*cmpfn)(struct List *, struct List *))
{
int res;
- List *item;
+ struct List *item;
statlist_for_each(item, list) {
res = cmpfn(item, newitem);
if (res == 0)
fatal("put_in_order: found existing elem");
else if (res > 0) {
- statlist_put_before(newitem, list, item);
+ statlist_put_before(list, newitem, item);
return;
}
}
- statlist_append(newitem, list);
+ statlist_append(list, newitem);
}
/* create new object if new, then return it */
/* find an existing database */
PgDatabase *find_database(const char *name)
{
- List *item, *tmp;
+ struct List *item, *tmp;
PgDatabase *db;
statlist_for_each(item, &database_list) {
db = container_of(item, PgDatabase, head);
db = container_of(item, PgDatabase, head);
if (strcmp(db->name, name) == 0) {
db->inactive_time = 0;
- statlist_remove(&db->head, &autodatabase_idle_list);
+ statlist_remove(&autodatabase_idle_list, &db->head);
put_in_order(&db->head, &database_list, cmp_database);
return db;
}
statlist_init(&pool->new_server_list, "new_server_list");
statlist_init(&pool->cancel_req_list, "cancel_req_list");
- list_append(&pool->map_head, &user->pool_list);
+ list_append(&user->pool_list, &pool->map_head);
/* keep pools in db/user order to make stats faster */
put_in_order(&pool->head, &pool_list, cmp_pool);
/* find pool object, create if needed */
PgPool *get_pool(PgDatabase *db, PgUser *user)
{
- List *item;
+ struct List *item;
PgPool *pool;
if (!db || !user)
/* client->cancel_key has requested client key */
void accept_cancel_request(PgSocket *req)
{
- List *pitem, *citem;
+ struct List *pitem, *citem;
PgPool *pool;
PgSocket *server = NULL, *client, *main_client = NULL;
void for_each_server(PgPool *pool, void (*func)(PgSocket *sk))
{
- List *item;
+ struct List *item;
statlist_for_each(item, &pool->idle_server_list)
func(container_of(item, PgSocket, head));
void tag_database_dirty(PgDatabase *db)
{
- List *item;
+ struct List *item;
PgPool *pool;
statlist_for_each(item, &pool_list) {
/* move objects from justfree_* to free_* lists */
void reuse_just_freed_objects(void)
{
- List *tmp, *item;
+ struct List *tmp, *item;
PgSocket *sk;
bool close_works = true;
/* we cannot log in at all, notify clients */
static void kill_pool_logins(PgPool *pool, PktHdr *errpkt)
{
- List *item, *tmp;
+ struct List *item, *tmp;
PgSocket *client;
const char *level, *msg;
* Store for pre-initialized objects of one type.
*/
struct ObjectCache {
- List head;
- StatList freelist;
- StatList slablist;
+ struct List head;
+ struct StatList freelist;
+ struct StatList slablist;
char name[32];
unsigned final_size;
unsigned total_count;
* Header for each slab.
*/
struct Slab {
- List head;
+ struct List head;
};
/* keep track of all caches */
safe_strcpy(cache->name, name, sizeof(cache->name));
cache->total_count = 0;
cache->init_func = init_func;
- statlist_append(&cache->head, &objcache_list);
+ statlist_append(&objcache_list, &cache->head);
if (align == 0)
cache->final_size = ALIGN(obj_size);
/* free all storage associated by cache */
void objcache_destroy(ObjectCache *cache)
{
- List *item, *tmp;
+ struct List *item, *tmp;
struct Slab *slab;
statlist_for_each_safe(item, &cache->slablist, tmp) {
slab = container_of(item, struct Slab, head);
free(slab);
}
- statlist_remove(&cache->head, &objcache_list);
+ statlist_remove(&objcache_list, &cache->head);
memset(cache, 0, sizeof(*cache));
obj_free(objcache_cache, cache);
}
/* init objects */
for (i = 0; i < count; i++) {
void *obj = area + i * cache->final_size;
- List *head = (List *)obj;
+ struct List *head = (struct List *)obj;
list_init(head);
- statlist_append(head, &cache->freelist);
+ statlist_append(&cache->freelist, head);
}
/* register to cache */
cache->total_count += count;
- statlist_append(&slab->head, &cache->slablist);
+ statlist_append(&cache->slablist, &slab->head);
}
/* get free object from cache */
void *obj_alloc(ObjectCache *cache)
{
- List *item = statlist_pop(&cache->freelist);
+ struct List *item = statlist_pop(&cache->freelist);
if (!item) {
grow(cache);
item = statlist_pop(&cache->freelist);
/* put object back to cache */
void obj_free(ObjectCache *cache, void *obj)
{
- List *item = obj;
+ struct List *item = obj;
list_init(item);
- statlist_prepend(item, &cache->freelist);
+ statlist_prepend(&cache->freelist, item);
}
/* total number of objects allocated from cache */
void objcache_stats(slab_stat_fn fn, void *arg)
{
ObjectCache *cache;
- List *item;
+ struct List *item;
statlist_for_each(item, &objcache_list) {
cache = container_of(item, ObjectCache, head);
avg.server_bytes, avg.query_time);
}
-bool admin_database_stats(PgSocket *client, StatList *pool_list)
+bool admin_database_stats(PgSocket *client, struct StatList *pool_list)
{
PgPool *pool;
- List *item;
+ struct List *item;
PgDatabase *cur_db = NULL;
PgStats st_total, st_db, old_db, old_total;
int rows = 0;
return true;
}
-bool show_stat_totals(PgSocket *client, StatList *pool_list)
+bool show_stat_totals(PgSocket *client, struct StatList *pool_list)
{
PgPool *pool;
- List *item;
+ struct List *item;
PgStats st_total, old_total, avg;
PktBuf *buf;
static void refresh_stats(int s, short flags, void *arg)
{
- List *item;
+ struct List *item;
PgPool *pool;
struct timeval period = { cf_stats_period, 0 };
PgStats old_total, cur_total, avg;
static void takeover_create_link(PgPool *pool, PgSocket *client)
{
- List *item;
+ struct List *item;
PgSocket *server;
statlist_for_each(item, &pool->active_server_list) {
}
/* clean the inappropriate places the old fds got stored in */
-static void takeover_clean_socket_list(StatList *list)
+static void takeover_clean_socket_list(struct StatList *list)
{
- List *item;
+ struct List *item;
PgSocket *sk;
statlist_for_each(item, list) {
sk = container_of(item, PgSocket, head);
/* all fds loaded, create links */
static void takeover_postprocess_fds(void)
{
- List *item, *item2;
+ struct List *item, *item2;
PgSocket *client;
PgPool *pool;