From: Maria Matejka Date: Tue, 7 Oct 2025 15:07:49 +0000 (+0200) Subject: Macro for entering birdloops with autoleave X-Git-Tag: v3.2.0~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c368ad59d8d39ba5bfe350fdb3641275ee3e3ec5;p=thirdparty%2Fbird.git Macro for entering birdloops with autoleave --- diff --git a/lib/io-loop.h b/lib/io-loop.h index d2c27754c..6d4f8ff4a 100644 --- a/lib/io-loop.h +++ b/lib/io-loop.h @@ -57,12 +57,20 @@ struct timeloop *birdloop_time_loop(struct birdloop *loop); /* Get birdloop's pool */ pool *birdloop_pool(struct birdloop *loop); -/* Enter and exit the birdloop */ +/* Enter the birdloop, leave at the end of the block. */ +#define BIRDLOOP_ENTER(_loop) CLEANUP(birdloop_leave_cleanup) UNUSED struct birdloop *_loop_entered = (birdloop_enter(_loop), (_loop)) + +/* Auxiliary cleanup function for BIRDLOOP_ENTER */ +void birdloop_leave_cleanup(struct birdloop **); + +/* Explicitly enter and exit the birdloop */ void birdloop_enter(struct birdloop *loop); void birdloop_leave(struct birdloop *loop); +/* Check whether we are actually inside a birdloop */ bool birdloop_inside(struct birdloop *loop); +/* Internal API, do not call */ void birdloop_mask_wakeups(struct birdloop *loop); void birdloop_unmask_wakeups(struct birdloop *loop); diff --git a/nest/rt-table.c b/nest/rt-table.c index 939c97969..dca2a5c19 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -3380,7 +3380,7 @@ rt_flowspec_link(rtable *src_pub, rtable *dst_pub) int lock_dst = 0; - birdloop_enter(dst_pub->loop); + BIRDLOOP_ENTER(dst_pub->loop); RT_LOCKED(src_pub, src) { @@ -3418,14 +3418,12 @@ rt_flowspec_link(rtable *src_pub, rtable *dst_pub) if (lock_dst) rt_lock_table(dst_pub); - - birdloop_leave(dst_pub->loop); } void rt_flowspec_unlink(rtable *src, rtable *dst) { - birdloop_enter(dst->loop); + BIRDLOOP_ENTER(dst->loop); bool unlock_dst = 0; @@ -3448,8 +3446,6 @@ rt_flowspec_unlink(rtable *src, rtable *dst) if (unlock_dst) rt_unlock_table(dst); - - birdloop_leave(dst->loop); } static void @@ -3617,7 +3613,7 @@ rt_setup(pool *pp, struct rtable_config *cf) /* Start the service thread */ struct birdloop *loop = birdloop_new(pp, DOMAIN_ORDER(service), cf->thread_group->group, "Routing table service %s", cf->name); - birdloop_enter(loop); + BIRDLOOP_ENTER(loop); pool *sp = birdloop_pool(loop); /* Create the table domain and pool */ @@ -3726,8 +3722,6 @@ rt_setup(pool *pp, struct rtable_config *cf) CALL(cf->master.setup, RT_PUB(t)); - birdloop_leave(t->loop); - return RT_PUB(t); } @@ -5084,18 +5078,19 @@ rt_commit(struct config *new, struct config *old) WALK_LIST(o, old->tables) { bool ok; - birdloop_enter(o->table->loop); - RT_LOCKED(o->table, tab) { - r = OBSREF_GET(tab->deleted) ? NULL : rt_find_table_config(new, o->name); - ok = r && !new->shutdown && rt_reconfigure(tab, r, o); + BIRDLOOP_ENTER(o->table->loop); + RT_LOCKED(o->table, tab) + { + r = OBSREF_GET(tab->deleted) ? NULL : rt_find_table_config(new, o->name); + ok = r && !new->shutdown && rt_reconfigure(tab, r, o); + } } - birdloop_leave(o->table->loop); if (ok) continue; - birdloop_enter(o->table->loop); + BIRDLOOP_ENTER(o->table->loop); RT_LOCKED(o->table, tab) { DBG("\t%s: deleted\n", o->name); @@ -5114,7 +5109,6 @@ rt_commit(struct config *new, struct config *old) } CALL(o->table->config->master.stop, o->table); - birdloop_leave(o->table->loop); } } diff --git a/sysdep/unix/io-loop.c b/sysdep/unix/io-loop.c index 7e8b31145..d0c5512ef 100644 --- a/sysdep/unix/io-loop.c +++ b/sysdep/unix/io-loop.c @@ -828,7 +828,7 @@ birdloop_balancer(void) uint dropped = 0; WALK_TLIST_DELSAFE(birdloop, loop, &this_thread->loops) { - birdloop_enter(loop); + BIRDLOOP_ENTER(loop); if (ev_active(&loop->event) && !loop->stopped && !birdloop_hot_potato(loop)) { /* Pass to another thread */ @@ -850,7 +850,6 @@ birdloop_balancer(void) break; } } - birdloop_leave(loop); } if (dropped) @@ -1009,9 +1008,8 @@ bird_thread_main(void *arg) WALK_TLIST(birdloop, loop, &thr->loops) { - birdloop_enter(loop); + BIRDLOOP_ENTER(loop); sockets_prepare(loop, &pfd); - birdloop_leave(loop); } ASSERT_DIE(pfd.loop.used == pfd.pfd.used); @@ -1090,7 +1088,7 @@ bird_thread_group_done(thread_group *gpub, TLIST_LIST(birdloop) *leftover_loops) while (!EMPTY_TLIST(birdloop, leftover_loops)) { struct birdloop *loop = THEAD(birdloop, leftover_loops); - birdloop_enter(loop); + BIRDLOOP_ENTER(loop); if (loop->thread_group == gpub) { birdloop_transfer(loop, gpub, default_thread_group); @@ -1098,7 +1096,6 @@ bird_thread_group_done(thread_group *gpub, TLIST_LIST(birdloop) *leftover_loops) birdloop_rem_node(leftover_loops, loop); birdloop_set_thread(loop, NULL); - birdloop_leave(loop); } thread_group_rem_node(&global_thread_group_list, gpub); @@ -1323,7 +1320,7 @@ static void bird_thread_stop(thread_group *gpub, struct config *old_config) { struct birdloop *tdl = birdloop_new(&root_pool, DOMAIN_ORDER(control), gpub, "Thread dropper"); - birdloop_enter(tdl); + BIRDLOOP_ENTER(tdl); TG_LOCKED(gpub, group) { @@ -1334,8 +1331,6 @@ bird_thread_stop(thread_group *gpub, struct config *old_config) OBSREF_SET(group->thread_dropper.conflock, old_config); ev_send_loop(tdl, &group->thread_dropper.event); } - - birdloop_leave(tdl); } void @@ -2269,6 +2264,13 @@ birdloop_leave(struct birdloop *loop) DG_UNLOCK(loop->time.domain); } +void +birdloop_leave_cleanup(struct birdloop **loop) +{ + if (*loop) + birdloop_leave(*loop); +} + void birdloop_mask_wakeups(struct birdloop *loop) {