qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/2] thread: add QemuRecMutex lock guards


From: Stefan Hajnoczi
Subject: [PATCH 1/2] thread: add QemuRecMutex lock guards
Date: Wed, 11 Mar 2020 12:36:23 +0000

This patch introduces two lock guard macros that automatically unlock a
QemuRecMutex:

  void f(void) {
      QEMU_REC_MUTEX_LOCK_GUARD(&mutex);
      if (!may_fail()) {
          return; /* automatically unlocks mutex */
      }
      ...
  }

and:

  WITH_QEMU_REC_MUTEX_LOCK_GUARD(&mutex) {
      if (!may_fail()) {
          return; /* automatically unlocks mutex */
      }
  }
  /* automatically unlocks mutex here */
  ...

Convert TCG plugins functions that benefit from these macros.  Manual
qemu_rec_mutex_lock/unlock() callers are left unmodified in cases where
clarity would not improve by switching to the macros.

Signed-off-by: Stefan Hajnoczi <address@hidden>
---
 include/qemu/thread.h | 26 ++++++++++++++++++++++++++
 plugins/core.c        |  6 ++----
 plugins/loader.c      | 15 +++++++--------
 3 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/include/qemu/thread.h b/include/qemu/thread.h
index 047db0307e..3993ab7b25 100644
--- a/include/qemu/thread.h
+++ b/include/qemu/thread.h
@@ -132,6 +132,32 @@ static inline int (qemu_rec_mutex_trylock)(QemuRecMutex 
*mutex)
 /* Prototypes for other functions are in thread-posix.h/thread-win32.h.  */
 void qemu_rec_mutex_init(QemuRecMutex *mutex);
 
+static inline QemuRecMutex *qemu_rec_mutex_auto_lock(QemuRecMutex *mutex)
+{
+    qemu_rec_mutex_lock(mutex);
+    return mutex;
+}
+
+static inline void qemu_rec_mutex_auto_unlock(QemuRecMutex *mutex)
+{
+    if (mutex) {
+        qemu_rec_mutex_unlock(mutex);
+    }
+}
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(QemuRecMutex, qemu_rec_mutex_auto_unlock)
+
+#define WITH_QEMU_REC_MUTEX_LOCK_GUARD_(mutex, var) \
+    for (g_autoptr(QemuRecMutex) var = qemu_rec_mutex_auto_lock((mutex)); \
+         var; qemu_rec_mutex_auto_unlock(var), var = NULL)
+
+#define WITH_QEMU_REC_MUTEX_LOCK_GUARD(mutex) \
+    WITH_QEMU_REC_MUTEX_LOCK_GUARD_((mutex), qemu_rec_mutex_auto##__COUNTER__)
+
+#define QEMU_REC_MUTEX_LOCK_GUARD(mutex) \
+    g_autoptr(QemuRecMutex) qemu_rec_mutex_auto##__COUNTER__ = \
+            qemu_rec_mutex_auto_lock((mutex))
+
 void qemu_cond_init(QemuCond *cond);
 void qemu_cond_destroy(QemuCond *cond);
 
diff --git a/plugins/core.c b/plugins/core.c
index ed863011ba..cf8c85de9c 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -150,11 +150,11 @@ do_plugin_register_cb(qemu_plugin_id_t id, enum 
qemu_plugin_event ev,
 {
     struct qemu_plugin_ctx *ctx;
 
-    qemu_rec_mutex_lock(&plugin.lock);
+    QEMU_REC_MUTEX_LOCK_GUARD(&plugin.lock);
     ctx = plugin_id_to_ctx_locked(id);
     /* if the plugin is on its way out, ignore this request */
     if (unlikely(ctx->uninstalling)) {
-        goto out_unlock;
+        return;
     }
     if (func) {
         struct qemu_plugin_cb *cb = ctx->callbacks[ev];
@@ -178,8 +178,6 @@ do_plugin_register_cb(qemu_plugin_id_t id, enum 
qemu_plugin_event ev,
     } else {
         plugin_unregister_cb__locked(ctx, ev);
     }
- out_unlock:
-    qemu_rec_mutex_unlock(&plugin.lock);
 }
 
 void plugin_register_cb(qemu_plugin_id_t id, enum qemu_plugin_event ev,
diff --git a/plugins/loader.c b/plugins/loader.c
index 15fc7e5515..9742c8d41d 100644
--- a/plugins/loader.c
+++ b/plugins/loader.c
@@ -367,15 +367,14 @@ void plugin_reset_uninstall(qemu_plugin_id_t id,
     struct qemu_plugin_reset_data *data;
     struct qemu_plugin_ctx *ctx;
 
-    qemu_rec_mutex_lock(&plugin.lock);
-    ctx = plugin_id_to_ctx_locked(id);
-    if (ctx->uninstalling || (reset && ctx->resetting)) {
-        qemu_rec_mutex_unlock(&plugin.lock);
-        return;
+    WITH_QEMU_REC_MUTEX_LOCK_GUARD(&plugin.lock) {
+        ctx = plugin_id_to_ctx_locked(id);
+        if (ctx->uninstalling || (reset && ctx->resetting)) {
+            return;
+        }
+        ctx->resetting = reset;
+        ctx->uninstalling = !reset;
     }
-    ctx->resetting = reset;
-    ctx->uninstalling = !reset;
-    qemu_rec_mutex_unlock(&plugin.lock);
 
     data = g_new(struct qemu_plugin_reset_data, 1);
     data->ctx = ctx;
-- 
2.24.1


reply via email to

[Prev in Thread] Current Thread [Next in Thread]