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


Reply via email to