extern struct birdloop main_birdloop;
/* Start a new birdloop owned by given pool and domain */
-struct birdloop *birdloop_new(pool *p, uint order, const char *name, btime max_latency);
+struct birdloop *birdloop_new(pool *p, uint order, btime max_latency, const char *fmt, ...);
/* Stop the loop. At the end, the @stopped callback is called unlocked in tail
* position to finish cleanup. Run birdloop_free() from that callback to free
/* Get birdloop's time heap */
struct timeloop *birdloop_time_loop(struct birdloop *loop);
+/* Get birdloop's pool */
+pool *birdloop_pool(struct birdloop *loop);
+
/* Enter and exit the birdloop */
void birdloop_enter(struct birdloop *loop);
void birdloop_leave(struct birdloop *loop);
}
pool *
-rp_newf(pool *p, const char *fmt, ...)
+rp_vnewf(pool *p, const char *fmt, va_list args)
{
pool *z = rp_new(p, NULL);
+ z->name = mb_vsprintf(p, fmt, args);
+ return z;
+}
+pool *
+rp_newf(pool *p, const char *fmt, ...)
+{
va_list args;
va_start(args, fmt);
- z->name = mb_vsprintf(p, fmt, args);
+ pool *z = rp_vnewf(p, fmt, args);
va_end(args);
return z;
#include "lib/lists.h"
+#include <stdarg.h>
+
struct resmem {
size_t effective; /* Memory actually used for data storage */
size_t overhead; /* Overhead memory imposed by allocator strategies */
pool *rp_new(pool *, const char *); /* Create a new pool */
pool *rp_newf(pool *, const char *, ...); /* Create a new pool with a formatted string as its name */
+pool *rp_vnewf(pool *, const char *, va_list); /* Create a new pool with a formatted string as its name */
void rp_init(pool *, const char *); /* Init a new pool */
void rp_initf(pool *, const char *, ...); /* Init a new pool with a formatted string as its name */
static inline void rp_free(pool *p) { rfree(&p->r); } /* Free the whole pool */
{
CALL(p->proto->cleanup, p);
- rp_free(p->pool);
- p->pool = NULL;
+ if (p->pool)
+ {
+ rp_free(p->pool);
+ p->pool = NULL;
+ }
p->active = 0;
proto_log_state_change(p);
birdloop_enter(&main_birdloop);
+ p->pool = NULL; /* is freed by birdloop_free() */
birdloop_free(p->loop);
p->loop = &main_birdloop;
+
proto_cleanup(p);
birdloop_leave(&main_birdloop);
DBG("Kicking %s up\n", p->name);
PD(p, "Starting");
- p->pool = rp_newf(proto_pool, "Protocol %s", p->cf->name);
-
if (graceful_restart_state == GRS_INIT)
p->gr_recovery = 1;
if (p->cf->loop_order != DOMAIN_ORDER(the_bird))
- p->loop = birdloop_new(p->pool, p->cf->loop_order, p->pool->name, p->cf->loop_max_latency);
+ {
+ p->loop = birdloop_new(proto_pool, p->cf->loop_order, p->cf->loop_max_latency, "Protocol %s", p->cf->name);
+ p->pool = birdloop_pool(p->loop);
+ }
+ else
+ p->pool = rp_newf(proto_pool, "Protocol %s", p->cf->name);
p->iface_sub.target = proto_event_list(p);
{
ASSERT_DIE(birdloop_inside(&main_birdloop));
- pool *p = rp_newf(pp, "Routing table %s", cf->name);
+ /* Start the service thread */
+ struct birdloop *loop = birdloop_new(pp, DOMAIN_ORDER(service), 0, "Routing table service %s", cf->name);
+ pool *sp = birdloop_pool(loop);
+ pool *p = rp_newf(sp, "Routing table data %s", cf->name);
+ /* Create the actual table */
struct rtable_private *t = ralloc(p, &rt_class);
t->rp = p;
+ t->loop = loop;
t->rte_slab = sl_new(p, sizeof(struct rte_storage));
t->flowspec_trie->ipv4 = (t->addr_type == NET_FLOW4);
}
- /* Start the service thread */
- t->loop = birdloop_new(p, DOMAIN_ORDER(service), mb_sprintf(p, "Routing table %s", t->name), 0);
+ /* Setup the service thread flag handler */
birdloop_enter(t->loop);
birdloop_flag_set_handler(t->loop, &t->fh);
birdloop_leave(t->loop);
RT_UNLOCK(RT_PUB(tab));
+ /* Everything is freed by freeing the loop */
birdloop_free(tab->loop);
- rfree(tab->rp);
config_del_obstacle(conf);
birdloop_leave(&main_birdloop);
#define THREAD_STACK_SIZE 65536 /* To be lowered in near future */
-static struct birdloop *birdloop_new_internal(pool *pp, uint order, const char *name, int request_pickup, struct birdloop_pickup_group *group);
+static struct birdloop *birdloop_new_no_pickup(pool *pp, uint order, const char *name, ...);
/*
* Nanosecond time for accounting purposes
return &loop->time;
}
+pool *
+birdloop_pool(struct birdloop *loop)
+{
+ return loop->pool;
+}
+
_Bool
birdloop_inside(struct birdloop *loop)
{
tmp_init(thr->pool);
init_list(&thr->loops);
- thr->meta = birdloop_new_internal(thr->pool, DOMAIN_ORDER(meta), "Thread Meta", 0, thr->group);
+ thr->meta = birdloop_new_no_pickup(thr->pool, DOMAIN_ORDER(meta), "Thread Meta");
thr->meta->thread = thr;
birdloop_enter(thr->meta);
if ((dif > 0) && !thread_dropper_running)
{
- struct birdloop *tdl = birdloop_new(&root_pool, DOMAIN_ORDER(control), "Thread dropper", group->max_latency);
+ struct birdloop *tdl = birdloop_new(&root_pool, DOMAIN_ORDER(control), group->max_latency, "Thread dropper");
event *tde = ev_new_init(tdl->pool, bird_thread_shutdown, NULL);
LOCK_DOMAIN(resource, group->domain);
}
static struct birdloop *
-birdloop_new_internal(pool *pp, uint order, const char *name, int request_pickup, struct birdloop_pickup_group *group)
+birdloop_vnew_internal(pool *pp, uint order, struct birdloop_pickup_group *group, const char *name, va_list args)
{
struct domain_generic *dg = domain_new(name, order);
- pool *p = rp_new(pp, name);
+ pool *p = rp_vnewf(pp, name, args);
struct birdloop *loop = mb_allocz(p, sizeof(struct birdloop));
loop->pool = p;
loop->event = (event) { .hook = birdloop_run, .data = loop, };
loop->timer = (timer) { .hook = birdloop_run_timer, .data = loop, };
- if (request_pickup)
+ if (group)
{
LOCK_DOMAIN(resource, group->domain);
add_tail(&group->loops, &loop->n);
return loop;
}
+static struct birdloop *
+birdloop_new_no_pickup(pool *pp, uint order, const char *name, ...)
+{
+ va_list args;
+ va_start(args, name);
+ struct birdloop *loop = birdloop_vnew_internal(pp, order, NULL, name, args);
+ va_end(args);
+ return loop;
+}
+
struct birdloop *
-birdloop_new(pool *pp, uint order, const char *name, btime max_latency)
+birdloop_new(pool *pp, uint order, btime max_latency, const char *name, ...)
{
- return birdloop_new_internal(pp, order, name, 1, max_latency ? &pickup_groups[1] : &pickup_groups[0]);
+ va_list args;
+ va_start(args, name);
+ struct birdloop *loop = birdloop_vnew_internal(pp, order, max_latency ? &pickup_groups[1] : &pickup_groups[0], name, args);
+ va_end(args);
+ return loop;
}
static void