]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Macro for entering birdloops with autoleave
authorMaria Matejka <mq@ucw.cz>
Tue, 7 Oct 2025 15:07:49 +0000 (17:07 +0200)
committerMaria Matejka <mq@ucw.cz>
Thu, 13 Nov 2025 11:25:03 +0000 (12:25 +0100)
lib/io-loop.h
nest/rt-table.c
sysdep/unix/io-loop.c

index d2c27754cd2910becc50a1897be92725ea95bcc6..6d4f8ff4ac8827e77c6240ee98fce90ab1624188 100644 (file)
@@ -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);
 
index 939c979692fc6129d797991bc946338d31086b4a..dca2a5c1984817ccaa828765d5021c374019e2fa 100644 (file)
@@ -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);
       }
     }
 
index 7e8b311450c2311528cae71853dfbf3b9c6cb76f..d0c5512ef4e9cc7ae70cfb823a8c1e768b7e62d2 100644 (file)
@@ -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)
 {