2
0
Fork 0

track event "names" for debugging

Change-Id: Ib8f2b589a6087de2355906a87bd2cd0c84bafcba
personal/stbuehler/wip
Stefan Bühler 2015-01-17 15:13:54 +01:00
parent 17d066bc57
commit 66bd6b22a2
17 changed files with 62 additions and 54 deletions

View File

@ -39,6 +39,7 @@ struct liEventBase {
liEventType type;
unsigned int keep_loop_alive:1, active: 1;
GList link_watchers; /* data points to loop */
const char *event_name; /* track what the event is used for */
liEventCallback callback;
};
@ -151,7 +152,7 @@ INLINE void li_event_set_callback_(liEventBase *base, liEventCallback callback);
#define li_event_set_callback(watcher, callback) (li_event_set_callback_(&(watcher)->base, callback))
/* defaults to keep_loop_alive = TRUE */
LI_API void li_event_io_init(liEventLoop *loop, liEventIO *io, liEventCallback callback, int fd, int events);
LI_API void li_event_io_init(liEventLoop *loop, const char *event_name, liEventIO *io, liEventCallback callback, int fd, int events);
LI_API void li_event_io_set_fd(liEventIO *io, int fd);
INLINE int li_event_io_fd(liEventIO *io);
LI_API void li_event_io_set_events(liEventIO *io, int events);
@ -161,32 +162,32 @@ INLINE liEventIO* li_event_io_from(liEventBase *base);
/* defaults to keep_loop_alive = TRUE */
/* timer will always stop when it triggers */
LI_API void li_event_timer_init(liEventLoop *loop, liEventTimer *timer, liEventCallback callback);
LI_API void li_event_timer_init(liEventLoop *loop, const char *event_name, liEventTimer *timer, liEventCallback callback);
INLINE void li_event_timer_once(liEventTimer *timer, li_tstamp timeout); /* also starts the watcher */
INLINE liEventTimer* li_event_timer_from(liEventBase *base);
/* defaults to keep_loop_alive = FALSE, starts immediately */
LI_API void li_event_async_init(liEventLoop *loop, liEventAsync *async, liEventCallback callback);
LI_API void li_event_async_init(liEventLoop *loop, const char *event_name, liEventAsync *async, liEventCallback callback);
INLINE void li_event_async_send(liEventAsync *async);
INLINE liEventAsync* li_event_async_from(liEventBase *base);
/* defaults to keep_loop_alive = TRUE, starts immediately */
LI_API void li_event_child_init(liEventLoop *loop, liEventChild *child, liEventCallback callback, int pid);
LI_API void li_event_child_init(liEventLoop *loop, const char *event_name, liEventChild *child, liEventCallback callback, int pid);
INLINE int li_event_child_pid(liEventChild *child);
INLINE int li_event_child_status(liEventChild *child);
INLINE liEventChild* li_event_child_from(liEventBase *base);
/* defaults to keep_loop_alive = FALSE, starts immediately */
LI_API void li_event_signal_init(liEventLoop *loop, liEventSignal *signal, liEventCallback callback, int signum);
LI_API void li_event_signal_init(liEventLoop *loop, const char *event_name, liEventSignal *signal, liEventCallback callback, int signum);
INLINE int li_event_signal_signum(liEventSignal *signal);
INLINE liEventSignal* li_event_signal_from(liEventBase *base);
/* defaults to keep_loop_alive = FALSE, starts immediately */
LI_API void li_event_prepare_init(liEventLoop *loop, liEventPrepare *prepare, liEventCallback callback);
LI_API void li_event_prepare_init(liEventLoop *loop, const char *event_name, liEventPrepare *prepare, liEventCallback callback);
INLINE liEventPrepare* li_event_prepare_from(liEventBase *base);
/* defaults to keep_loop_alive = FALSE, starts immediately */
LI_API void li_event_check_init(liEventLoop *loop, liEventCheck *check, liEventCallback callback);
LI_API void li_event_check_init(liEventLoop *loop, const char *event_name, liEventCheck *check, liEventCallback callback);
INLINE liEventCheck* li_event_check_from(liEventBase *base);

View File

@ -978,7 +978,7 @@ static gboolean core_init(liServer *srv, liPlugin *p) {
li_angel_plugin_add_angel_cb(p, "reached-state", core_reached_state);
li_angel_plugin_add_angel_cb(p, "log-open-file", core_log_open_file);
li_event_signal_init(&srv->loop, &config->sig_hup, core_handle_sig_hup, SIGHUP);
li_event_signal_init(&srv->loop, "angel SIGHUP", &config->sig_hup, core_handle_sig_hup, SIGHUP);
return TRUE;
}

View File

@ -88,7 +88,7 @@ liErrorPipe* li_error_pipe_new(liServer *srv, liErrorPipeCB cb, gpointer ctx) {
epipe->srv = srv;
epipe->cb = cb;
epipe->ctx = ctx;
li_event_io_init(&srv->loop, &epipe->fd_watcher, error_pipe_cb, fds[0], LI_EV_READ);
li_event_io_init(&srv->loop, "angel error-pipe", &epipe->fd_watcher, error_pipe_cb, fds[0], LI_EV_READ);
epipe->fds[0] = fds[0];
epipe->fds[1] = fds[1];

View File

@ -18,9 +18,9 @@ liServer* li_server_new(const gchar *module_dir, gboolean module_resident) {
li_event_loop_init(&srv->loop, ev_default_loop(0));
li_event_signal_init(&srv->loop, &srv->sig_w_INT, sigint_cb, SIGINT);
li_event_signal_init(&srv->loop, &srv->sig_w_TERM, sigint_cb, SIGTERM);
li_event_signal_init(&srv->loop, &srv->sig_w_PIPE, sigpipe_cb, SIGPIPE);
li_event_signal_init(&srv->loop, "angel SIGINT", &srv->sig_w_INT, sigint_cb, SIGINT);
li_event_signal_init(&srv->loop, "angel SIGTERM", &srv->sig_w_TERM, sigint_cb, SIGTERM);
li_event_signal_init(&srv->loop, "angel SIGPIPE", &srv->sig_w_PIPE, sigpipe_cb, SIGPIPE);
li_log_init(srv);
li_plugins_init(srv, module_dir, module_resident);
@ -178,7 +178,7 @@ static void instance_spawn(liInstance *i) {
close(confd[1]);
li_event_clear(&i->child_watcher);
li_event_child_init(&i->srv->loop, &i->child_watcher, instance_child_cb, i->proc->child_pid);
li_event_child_init(&i->srv->loop, "lighttpd2-worker", &i->child_watcher, instance_child_cb, i->proc->child_pid);
i->s_cur = LI_INSTANCE_DOWN;
li_instance_acquire(i);
DEBUG(i->srv, "Instance (%i) spawned: %s", i->proc->child_pid, i->ic->cmd[0]);

View File

@ -395,11 +395,11 @@ liAngelConnection* li_angel_connection_new(liEventLoop *loop, int fd, gpointer d
acon->call_id_list = li_idlist_new(65535);
acon->call_table = g_ptr_array_new();
li_event_io_init(loop, &acon->fd_watcher, angel_connection_io_cb, fd, LI_EV_READ);
li_event_io_init(loop, "angel connection", &acon->fd_watcher, angel_connection_io_cb, fd, LI_EV_READ);
li_event_set_keep_loop_alive(&acon->fd_watcher, FALSE);
li_event_start(&acon->fd_watcher);
li_event_async_init(loop, &acon->out_notify_watcher, angel_connection_out_notify_cb);
li_event_async_init(loop, "angel out-notify", &acon->out_notify_watcher, angel_connection_out_notify_cb);
acon->out = g_queue_new();
acon->in.data = g_string_sized_new(1024);
@ -504,9 +504,9 @@ liAngelCall *li_angel_call_new(liEventLoop *loop, liAngelCallCB callback, li_tst
g_assert(NULL != callback);
call->callback = callback;
li_event_timer_init(loop, &call->timeout_watcher, angel_call_timeout_cb);
li_event_timer_init(loop, "angel call timeout", &call->timeout_watcher, angel_call_timeout_cb);
li_event_timer_once(&call->timeout_watcher, timeout);
li_event_async_init(loop, &call->result_watcher, angel_call_result_cb);
li_event_async_init(loop, "angel call result", &call->result_watcher, angel_call_result_cb);
call->id = -1;
return call;

View File

@ -171,10 +171,11 @@ static int io_events_to_libev(int events) {
return revents;
}
void li_event_io_init(liEventLoop *loop, liEventIO *io, liEventCallback callback, int fd, int events) {
void li_event_io_init(liEventLoop *loop, const char *event_name, liEventIO *io, liEventCallback callback, int fd, int events) {
memset(io, 0, sizeof(*io));
io->base.type = LI_EVT_IO;
io->base.keep_loop_alive = 1;
io->base.event_name = event_name;
io->base.callback = callback;
io->events = events;
ev_init(&io->libevmess.w, NULL);
@ -251,10 +252,11 @@ static void event_timer_cb(struct ev_loop *loop, ev_timer *w, int revents) {
timer->base.callback(&timer->base, LI_EV_WAKEUP);
}
void li_event_timer_init(liEventLoop *loop, liEventTimer *timer, liEventCallback callback) {
void li_event_timer_init(liEventLoop *loop, const char *event_name, liEventTimer *timer, liEventCallback callback) {
memset(timer, 0, sizeof(*timer));
timer->base.type = LI_EVT_TIMER;
timer->base.keep_loop_alive = 1;
timer->base.event_name = event_name;
timer->base.callback = callback;
ev_init(&timer->libevmess.w, NULL);
ev_set_cb(&timer->libevmess.timer, event_timer_cb);
@ -273,10 +275,11 @@ static void event_async_cb(struct ev_loop *loop, ev_async *w, int revents) {
async->base.callback(&async->base, LI_EV_WAKEUP);
}
void li_event_async_init(liEventLoop *loop, liEventAsync *async, liEventCallback callback) {
void li_event_async_init(liEventLoop *loop, const char *event_name, liEventAsync *async, liEventCallback callback) {
memset(async, 0, sizeof(*async));
async->base.type = LI_EVT_ASYNC;
async->base.keep_loop_alive = 0;
async->base.event_name = event_name;
async->base.callback = callback;
ev_init(&async->libevmess.w, NULL);
ev_set_cb(&async->libevmess.async, event_async_cb);
@ -302,10 +305,11 @@ static void event_child_cb(struct ev_loop *loop, ev_child *w, int revents) {
child->base.callback(&child->base, LI_EV_WAKEUP);
}
void li_event_child_init(liEventLoop *loop, liEventChild *child, liEventCallback callback, int pid) {
void li_event_child_init(liEventLoop *loop, const char *event_name, liEventChild *child, liEventCallback callback, int pid) {
memset(child, 0, sizeof(*child));
child->base.type = LI_EVT_CHILD;
child->base.keep_loop_alive = 1;
child->base.event_name = event_name;
child->base.callback = callback;
ev_init(&child->libevmess.w, NULL);
ev_child_set(&child->libevmess.child, pid, 0);
@ -326,10 +330,11 @@ static void event_signal_cb(struct ev_loop *loop, ev_signal *w, int revents) {
sig->base.callback(&sig->base, LI_EV_WAKEUP);
}
void li_event_signal_init(liEventLoop *loop, liEventSignal *sig, liEventCallback callback, int signum) {
void li_event_signal_init(liEventLoop *loop, const char *event_name, liEventSignal *sig, liEventCallback callback, int signum) {
memset(sig, 0, sizeof(*sig));
sig->base.type = LI_EVT_SIGNAL;
sig->base.keep_loop_alive = 0;
sig->base.event_name = event_name;
sig->base.callback = callback;
ev_init(&sig->libevmess.w, NULL);
ev_signal_set(&sig->libevmess.sig, signum);
@ -350,10 +355,11 @@ static void event_prepare_cb(struct ev_loop *loop, ev_prepare *w, int revents) {
prepare->base.callback(&prepare->base, LI_EV_WAKEUP);
}
void li_event_prepare_init(liEventLoop *loop, liEventPrepare *prepare, liEventCallback callback) {
void li_event_prepare_init(liEventLoop *loop, const char *event_name, liEventPrepare *prepare, liEventCallback callback) {
memset(prepare, 0, sizeof(*prepare));
prepare->base.type = LI_EVT_PREPARE;
prepare->base.keep_loop_alive = 0;
prepare->base.event_name = event_name;
prepare->base.callback = callback;
ev_init(&prepare->libevmess.w, NULL);
ev_set_cb(&prepare->libevmess.prepare, event_prepare_cb);
@ -373,10 +379,11 @@ static void event_check_cb(struct ev_loop *loop, ev_check *w, int revents) {
check->base.callback(&check->base, LI_EV_WAKEUP);
}
void li_event_check_init(liEventLoop *loop, liEventCheck *check, liEventCallback callback) {
void li_event_check_init(liEventLoop *loop, const char *event_name, liEventCheck *check, liEventCallback callback) {
memset(check, 0, sizeof(*check));
check->base.type = LI_EVT_CHECK;
check->base.keep_loop_alive = 0;
check->base.event_name = event_name;
check->base.callback = callback;
ev_init(&check->libevmess.w, NULL);
ev_set_cb(&check->libevmess.check, event_check_cb);

View File

@ -61,9 +61,9 @@ static void job_async_queue_cb(liEventBase *watcher, int events) {
void li_job_queue_init(liJobQueue* jq, liEventLoop *loop) {
li_event_prepare_init(loop, &jq->prepare_watcher, job_queue_prepare_cb);
li_event_async_init(loop, &jq->async_queue_watcher, job_async_queue_cb);
li_event_timer_init(loop, &jq->queue_watcher, job_queue_watcher_cb);
li_event_prepare_init(loop, "jobqueue", &jq->prepare_watcher, job_queue_prepare_cb);
li_event_async_init(loop, "jobqueue", &jq->async_queue_watcher, job_async_queue_cb);
li_event_timer_init(loop, "jobqueue", &jq->queue_watcher, job_queue_watcher_cb);
/* job queue */
g_queue_init(&jq->queue);

View File

@ -801,7 +801,7 @@ liMemcachedCon* li_memcached_con_new(liEventLoop *loop, liSocketAddress addr) {
con->tmpstr = g_string_sized_new(511);
con->fd = -1;
li_event_io_init(loop, &con->con_watcher, memcached_io_cb, -1, 0);
li_event_io_init(loop, "memcached", &con->con_watcher, memcached_io_cb, -1, 0);
li_event_set_keep_loop_alive(&con->con_watcher, FALSE);
memcached_connect(con);

View File

@ -57,7 +57,7 @@ static void run_tasklet(gpointer data, gpointer userdata) {
liTaskletPool* li_tasklet_pool_new(liEventLoop *loop, gint threads) {
liTaskletPool *pool = g_slice_new0(liTaskletPool);
li_event_async_init(loop, &pool->finished_watcher, finished_watcher_cb);
li_event_async_init(loop, "tasklet pool", &pool->finished_watcher, finished_watcher_cb);
pool->finished = g_async_queue_new();

View File

@ -9,7 +9,7 @@ static void wq_cb(liEventBase *watcher, int events) {
}
void li_waitqueue_init(liWaitQueue *queue, liEventLoop *loop, liWaitQueueCB callback, gdouble delay, gpointer data) {
li_event_timer_init(loop, &queue->timer, wq_cb);
li_event_timer_init(loop, "waitqueue", &queue->timer, wq_cb);
queue->head = queue->tail = NULL;
queue->delay = delay;

View File

@ -240,7 +240,7 @@ static void S_backend_pool_worker_insert_connected(liBackendWorkerPool *wpool, i
liBackendConnection_p *con = backend_connection_new(wpool);
liBackendPool_p *pool = wpool->pool;
li_event_io_init(&wpool->wrk->loop, &con->public.watcher, NULL, fd, 0);
li_event_io_init(&wpool->wrk->loop, "backend connection", &con->public.watcher, NULL, fd, 0);
li_event_set_keep_loop_alive(&con->public.watcher, FALSE);
BACKEND_THREAD_CB(new, pool, wpool->wrk, con);
@ -386,7 +386,7 @@ static void backend_con_watch_connect_cb(liEventBase *watcher, int events) {
static void S_backend_pool_worker_insert_pending(liBackendWorkerPool *wpool, int fd) {
liBackendConnection_p *con = backend_connection_new(wpool);
li_event_io_init(&wpool->wrk->loop, &con->public.watcher, backend_con_watch_connect_cb, fd, LI_EV_READ | LI_EV_WRITE);
li_event_io_init(&wpool->wrk->loop, "backend connection", &con->public.watcher, backend_con_watch_connect_cb, fd, LI_EV_READ | LI_EV_WRITE);
li_event_set_keep_loop_alive(&con->public.watcher, FALSE);
li_event_start(&con->public.watcher);
@ -775,12 +775,12 @@ static gpointer backend_pool_worker_init(liWorker *wrk, gpointer fdata) {
if (wpool->initialized) return NULL;
li_event_async_init(&wrk->loop, &wpool->wakeup, backend_pool_worker_run);
li_event_async_init(&wrk->loop, "backend pool", &wpool->wakeup, backend_pool_worker_run);
if (idle_timeout < 1) idle_timeout = 5;
li_waitqueue_init(&wpool->idle_queue, &wrk->loop, backend_pool_worker_idle_timeout, idle_timeout, wpool);
li_waitqueue_init(&wpool->connect_queue, &wrk->loop, backend_pool_worker_connect_timeout, pool->public.config->connect_timeout, wpool);
li_event_timer_init(&wrk->loop, &wpool->wait_queue_timer, backend_pool_wait_queue_timeout);
li_event_timer_init(&wrk->loop, "backend pool", &wpool->wait_queue_timer, backend_pool_wait_queue_timeout);
li_event_set_keep_loop_alive(&wpool->wait_queue_timer, FALSE);
wpool->initialized = TRUE;

View File

@ -706,7 +706,7 @@ liConnection* li_connection_new(liWorker *wrk) {
con->keep_alive_data.link = NULL;
con->keep_alive_data.timeout = 0;
con->keep_alive_data.max_idle = 0;
li_event_timer_init(&wrk->loop, &con->keep_alive_data.watcher, connection_keepalive_cb);
li_event_timer_init(&wrk->loop, "connection keep-alive timeout", &con->keep_alive_data.watcher, connection_keepalive_cb);
con->io_timeout_elem.data = con;

View File

@ -108,7 +108,7 @@ static void log_close_cb(liWaitQueue *wq, gpointer data) {
void li_log_init(liServer *srv) {
li_event_loop_init(&srv->logs.loop, ev_loop_new(EVFLAG_AUTO));
li_event_async_init(&srv->logs.loop, &srv->logs.watcher, log_watcher_cb);
li_event_async_init(&srv->logs.loop, "log", &srv->logs.watcher, log_watcher_cb);
srv->logs.targets = li_radixtree_new();
li_waitqueue_init(&srv->logs.close_queue, &srv->logs.loop, log_close_cb, LOG_DEFAULT_TTL, srv);
srv->logs.timestamp.format = g_string_new_len(CONST_STR_LEN(LOG_DEFAULT_TS_FORMAT));

View File

@ -22,7 +22,7 @@ static liServerSocket* server_socket_new(liServer *srv, int fd) {
sock->local_addr = li_sockaddr_local_from_socket(fd);
sock->refcount = 1;
li_fd_no_block(fd);
li_event_io_init(&srv->main_worker->loop, &sock->watcher, li_server_listen_cb, fd, LI_EV_READ);
li_event_io_init(&srv->main_worker->loop, "server socket", &sock->watcher, li_server_listen_cb, fd, LI_EV_READ);
return sock;
}
@ -287,15 +287,15 @@ void li_server_loop_init(liServer *srv) {
loop = &srv->main_worker->loop;
li_event_async_init(loop, &srv->state_ready_watcher, state_ready_cb);
li_event_async_init(loop, "server state ready", &srv->state_ready_watcher, state_ready_cb);
li_event_timer_init(loop, &srv->srv_1sec_timer, li_server_1sec_timer);
li_event_timer_init(loop, "server 1sec", &srv->srv_1sec_timer, li_server_1sec_timer);
li_event_set_keep_loop_alive(&srv->srv_1sec_timer, FALSE);
li_event_timer_once(&srv->srv_1sec_timer, 1);
li_event_signal_init(loop, &srv->sig_w_INT, sigint_cb, SIGINT);
li_event_signal_init(loop, &srv->sig_w_TERM, sigint_cb, SIGTERM);
li_event_signal_init(loop, &srv->sig_w_PIPE, sigpipe_cb, SIGPIPE);
li_event_signal_init(loop, "server SIGINT", &srv->sig_w_INT, sigint_cb, SIGINT);
li_event_signal_init(loop, "server SIGTERM", &srv->sig_w_TERM, sigint_cb, SIGTERM);
li_event_signal_init(loop, "server SIGPIPE", &srv->sig_w_PIPE, sigpipe_cb, SIGPIPE);
li_log_init(srv);
}

View File

@ -487,7 +487,7 @@ liIOStream* li_iostream_new(liWorker *wrk, int fd, liIOStreamCB cb, gpointer dat
iostream->write_timeout_queue = NULL;
li_event_io_init(&wrk->loop, &iostream->io_watcher, iostream_io_cb, fd, LI_EV_READ);
li_event_io_init(&wrk->loop, "iostream", &iostream->io_watcher, iostream_io_cb, fd, LI_EV_READ);
iostream->in_closed = iostream->out_closed = iostream->can_read = FALSE;
iostream->can_write = TRUE;

View File

@ -285,7 +285,7 @@ liWorker* li_worker_new(liServer *srv, struct ev_loop *loop) {
li_lua_init(&wrk->LL, srv, wrk);
g_queue_init(&wrk->keep_alive_queue);
li_event_timer_init(&wrk->loop, &wrk->keep_alive_timer, worker_keepalive_cb);
li_event_timer_init(&wrk->loop, "worker connection keep-alive", &wrk->keep_alive_timer, worker_keepalive_cb);
wrk->connections_active = 0;
wrk->connections = g_array_new(FALSE, TRUE, sizeof(liConnection*));
@ -307,20 +307,20 @@ liWorker* li_worker_new(liServer *srv, struct ev_loop *loop) {
g_array_index(wrk->timestamps_local, liWorkerTS, i).str = g_string_sized_new(255);
}
li_event_prepare_init(&wrk->loop, &wrk->loop_prepare, li_worker_prepare_cb);
li_event_async_init(&wrk->loop, &wrk->worker_stop_watcher, li_worker_stop_cb);
li_event_async_init(&wrk->loop, &wrk->worker_stopping_watcher, li_worker_stopping_cb);
li_event_async_init(&wrk->loop, &wrk->worker_exit_watcher, li_worker_exit_cb);
li_event_async_init(&wrk->loop, &wrk->worker_suspend_watcher, li_worker_suspend_cb);
li_event_prepare_init(&wrk->loop, "worker flush logs", &wrk->loop_prepare, li_worker_prepare_cb);
li_event_async_init(&wrk->loop, "worker stop", &wrk->worker_stop_watcher, li_worker_stop_cb);
li_event_async_init(&wrk->loop, "worker stopping", &wrk->worker_stopping_watcher, li_worker_stopping_cb);
li_event_async_init(&wrk->loop, "worker exit", &wrk->worker_exit_watcher, li_worker_exit_cb);
li_event_async_init(&wrk->loop, "worker suspend", &wrk->worker_suspend_watcher, li_worker_suspend_cb);
li_event_async_init(&wrk->loop, &wrk->new_con_watcher, li_worker_new_con_cb);
li_event_async_init(&wrk->loop, "worker new connection", &wrk->new_con_watcher, li_worker_new_con_cb);
wrk->new_con_queue = g_async_queue_new();
li_event_timer_init(&wrk->loop, &wrk->stats_watcher, worker_stats_watcher_cb);
li_event_timer_init(&wrk->loop, "worker stats update", &wrk->stats_watcher, worker_stats_watcher_cb);
li_event_set_keep_loop_alive(&wrk->stats_watcher, FALSE);
li_event_timer_once(&wrk->stats_watcher, 1);
li_event_async_init(&wrk->loop, &wrk->collect_watcher, li_collect_watcher_cb);
li_event_async_init(&wrk->loop, "worker collect", &wrk->collect_watcher, li_collect_watcher_cb);
wrk->collect_queue = g_async_queue_new();
/* io timeout timer */

View File

@ -84,10 +84,10 @@ static balancer* balancer_new(liWorker *wrk, liPlugin *p, balancer_method method
b->backlog_limit = -1;
li_event_timer_init(&wrk->loop, &b->backlog_timer, balancer_timer_cb);
li_event_timer_init(&wrk->loop, "balancer", &b->backlog_timer, balancer_timer_cb);
li_event_set_keep_loop_alive(&b->backlog_timer, FALSE);
li_event_async_init(&wrk->loop, &b->async, balancer_async_cb);
li_event_async_init(&wrk->loop, "balancer", &b->async, balancer_async_cb);
return b;
}