]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Objects guarded by their loops
authorMaria Matejka <mq@ucw.cz>
Sat, 11 Oct 2025 13:14:10 +0000 (15:14 +0200)
committerMaria Matejka <mq@ucw.cz>
Thu, 13 Nov 2025 11:25:03 +0000 (12:25 +0100)
lib/io-loop.h

index 6d4f8ff4ac8827e77c6240ee98fce90ab1624188..123d96840599ac2f4dea3351cf43b9dbfe37165c 100644 (file)
@@ -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);