Use the same trick used by Linux (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fcc22ac5baf06dd17193de44b60dbcee): use the compound statement expression with "goto" jumping past the "loop", effectively leaving only the subscope part of the loop semantics.
The old loop had to handle auto_unlock to set the var to NULL, but now it can rely on autoptr. Suggested-by: Akihiko Odaki <[email protected]> Signed-off-by: Marc-André Lureau <[email protected]> --- include/qemu/lockable.h | 19 ++++++++++++------- include/qemu/rcu.h | 17 +++++++++++------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/include/qemu/lockable.h b/include/qemu/lockable.h index 66713bd42921..2704a1ec077d 100644 --- a/include/qemu/lockable.h +++ b/include/qemu/lockable.h @@ -130,11 +130,15 @@ static inline void qemu_lockable_auto_unlock(QemuLockable *x) G_DEFINE_AUTOPTR_CLEANUP_FUNC(QemuLockable, qemu_lockable_auto_unlock) -#define WITH_QEMU_LOCK_GUARD_(x, var) \ - for (g_autoptr(QemuLockable) var = \ - qemu_lockable_auto_lock(QEMU_MAKE_LOCKABLE_NONNULL((x))); \ - var; \ - qemu_lockable_auto_unlock(var), var = NULL) +#define WITH_QEMU_LOCK_GUARD_(x, var, label) \ + for (g_autoptr(QemuLockable) var = \ + qemu_lockable_auto_lock( \ + QEMU_MAKE_LOCKABLE_NONNULL((x))); \ + ; ({ goto label; })) \ + if (0) { \ + label: \ + break; \ + } else /** * WITH_QEMU_LOCK_GUARD - Lock a lock object for scope @@ -158,8 +162,9 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(QemuLockable, qemu_lockable_auto_unlock) * ... * } */ -#define WITH_QEMU_LOCK_GUARD(x) \ - WITH_QEMU_LOCK_GUARD_((x), glue(qemu_lockable_auto, __COUNTER__)) +#define WITH_QEMU_LOCK_GUARD(x) \ + WITH_QEMU_LOCK_GUARD_((x), glue(qemu_lockable_auto, __COUNTER__), \ + glue(qemu_lockable_label_, __COUNTER__)) /** * QEMU_LOCK_GUARD - Lock an object until the end of the scope diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h index 020dbe4d8b77..41d02255ceae 100644 --- a/include/qemu/rcu.h +++ b/include/qemu/rcu.h @@ -178,12 +178,17 @@ static inline void rcu_read_auto_unlock(RCUReadAuto *r) G_DEFINE_AUTOPTR_CLEANUP_FUNC(RCUReadAuto, rcu_read_auto_unlock) -#define WITH_RCU_READ_LOCK_GUARD() \ - WITH_RCU_READ_LOCK_GUARD_(glue(_rcu_read_auto, __COUNTER__)) - -#define WITH_RCU_READ_LOCK_GUARD_(var) \ - for (g_autoptr(RCUReadAuto) var = rcu_read_auto_lock(); \ - (var); rcu_read_auto_unlock(var), (var) = NULL) +#define WITH_RCU_READ_LOCK_GUARD() \ + WITH_RCU_READ_LOCK_GUARD_(glue(_rcu_read_auto, __COUNTER__), \ + glue(_rcu_read_label_, __COUNTER__)) + +#define WITH_RCU_READ_LOCK_GUARD_(var, label) \ + for (g_autoptr(RCUReadAuto) var = rcu_read_auto_lock(); \ + ; ({ goto label; })) \ + if (0) { \ + label: \ + break; \ + } else #define RCU_READ_LOCK_GUARD() \ g_autoptr(RCUReadAuto) _rcu_read_auto __attribute__((unused)) = rcu_read_auto_lock() -- 2.55.0
