From: Maria Matejka Date: Sat, 11 Oct 2025 13:14:10 +0000 (+0200) Subject: Objects guarded by their loops X-Git-Tag: v3.2.0~32 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ff964c58ed3708da377a81ab11a14997887a376e;p=thirdparty%2Fbird.git Objects guarded by their loops --- diff --git a/lib/io-loop.h b/lib/io-loop.h index 6d4f8ff4a..123d96840 100644 --- a/lib/io-loop.h +++ b/lib/io-loop.h @@ -60,9 +60,31 @@ pool *birdloop_pool(struct birdloop *loop); /* 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)) +/* Prematurely leave the birdloop */ +#define BIRDLOOP_LEAVE(_loop) (birdloop_leave_cleanup(&_loop), _loop = NULL); + /* Auxiliary cleanup function for BIRDLOOP_ENTER */ void birdloop_leave_cleanup(struct birdloop **); +/* Structures similar to LOBJ_*, see lib/locking.h */ +#define BLO_UNLOCK_CLEANUP_NAME(_stem) _blo__##_stem##_unlock_cleanup +#define BLO_UNLOCK_CLEANUP(_stem) \ + static inline void BLO_UNLOCK_CLEANUP_NAME(_stem)(struct _stem##_private **obj) { \ + if (!*obj) return; \ + ASSERT_DIE(birdloop_inside((*obj)->lock)); \ + ASSERT_DIE((*obj)->locked_at == obj); \ + (*obj)->locked_at = NULL; \ + birdloop_leave((*obj)->lock); \ + } + +#define BLO_LOCK(_obj, _pobj, _stem) \ + CLEANUP(BLO_UNLOCK_CLEANUP_NAME(_stem)) struct _stem##_private *_pobj = &(_obj)->priv; birdloop_enter(_pobj->lock); _pobj->locked_at = &_pobj; + +#define BLO_LOCKED(_obj, _pobj, _stem) \ + for (CLEANUP(BLO_UNLOCK_CLEANUP_NAME(_stem)) struct _stem##_private *_pobj = &(_obj)->priv; \ + _pobj ? (birdloop_enter(_pobj->lock), _pobj->locked_at = &pobj) : NULL; \ + BLO_UNLOCK_CLEANUP_NAME(_stem)(&_pobj), _pobj = NULL) + /* Explicitly enter and exit the birdloop */ void birdloop_enter(struct birdloop *loop); void birdloop_leave(struct birdloop *loop);