diff --git a/lib/io-loop.h b/lib/io-loop.h index 877cd5ce..b0d3d6cc 100644 --- a/lib/io-loop.h +++ b/lib/io-loop.h @@ -17,7 +17,7 @@ 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 @@ -32,6 +32,9 @@ event_list *birdloop_event_list(struct birdloop *loop); /* 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); diff --git a/lib/resource.c b/lib/resource.c index 0006bc8d..b1b89bdf 100644 --- a/lib/resource.c +++ b/lib/resource.c @@ -64,13 +64,19 @@ rp_new(pool *p, const char *name) } 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; diff --git a/lib/resource.h b/lib/resource.h index 64803778..2adb9de0 100644 --- a/lib/resource.h +++ b/lib/resource.h @@ -12,6 +12,8 @@ #include "lib/lists.h" +#include + struct resmem { size_t effective; /* Memory actually used for data storage */ size_t overhead; /* Overhead memory imposed by allocator strategies */ @@ -60,6 +62,7 @@ void *ralloc(pool *, struct resclass *); 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 */ diff --git a/nest/proto.c b/nest/proto.c index 1b25dfe9..d6269272 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -1116,8 +1116,11 @@ proto_cleanup(struct proto *p) { 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); @@ -1131,8 +1134,10 @@ proto_loop_stopped(void *ptr) 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); @@ -1214,13 +1219,16 @@ proto_start(struct proto *p) 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); diff --git a/nest/rt-table.c b/nest/rt-table.c index cec13318..9629db2c 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -2845,10 +2845,15 @@ rt_setup(pool *pp, struct rtable_config *cf) { 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)); @@ -2906,8 +2911,7 @@ rt_setup(pool *pp, struct rtable_config *cf) 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); @@ -4073,8 +4077,8 @@ rt_delete(void *tab_) 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); diff --git a/sysdep/unix/io-loop.c b/sysdep/unix/io-loop.c index 8481bb6e..701eddf7 100644 --- a/sysdep/unix/io-loop.c +++ b/sysdep/unix/io-loop.c @@ -31,7 +31,7 @@ #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 @@ -87,6 +87,12 @@ birdloop_time_loop(struct birdloop *loop) return &loop->time; } +pool * +birdloop_pool(struct birdloop *loop) +{ + return loop->pool; +} + _Bool birdloop_inside(struct birdloop *loop) { @@ -627,7 +633,7 @@ bird_thread_main(void *arg) 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); @@ -885,7 +891,7 @@ bird_thread_commit(struct config *new, struct config *old UNUSED) 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); @@ -1178,11 +1184,11 @@ birdloop_run_timer(timer *tm) } 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; @@ -1200,7 +1206,7 @@ birdloop_new_internal(pool *pp, uint order, const char *name, int request_pickup 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); @@ -1218,10 +1224,24 @@ birdloop_new_internal(pool *pp, uint order, const char *name, int request_pickup return loop; } -struct birdloop * -birdloop_new(pool *pp, uint order, const char *name, btime max_latency) +static struct birdloop * +birdloop_new_no_pickup(pool *pp, uint order, 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, NULL, name, args); + va_end(args); + return loop; +} + +struct birdloop * +birdloop_new(pool *pp, uint order, btime max_latency, const char *name, ...) +{ + 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