All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
	"Alex Bennée" <alex.bennee@linaro.org>,
	"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
	"Stefan Hajnoczi" <stefanha@redhat.com>
Subject: [PATCH 1/2] thread: add QemuRecMutex lock guards
Date: Wed, 11 Mar 2020 12:36:23 +0000	[thread overview]
Message-ID: <20200311123624.277221-2-stefanha@redhat.com> (raw)
In-Reply-To: <20200311123624.277221-1-stefanha@redhat.com>

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 <stefanha@redhat.com>
---
 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	other threads:[~2020-03-11 12:39 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-11 12:36 [PATCH 0/2] thread: add lock guard macros Stefan Hajnoczi
2020-03-11 12:36 ` Stefan Hajnoczi [this message]
2020-03-11 12:36 ` [PATCH 2/2] thread: add QemuMutex lock guards Stefan Hajnoczi
2020-03-11 12:52 ` [PATCH 0/2] thread: add lock guard macros Paolo Bonzini
2020-03-11 17:06   ` Stefan Hajnoczi
2020-03-11 13:20 ` no-reply
2020-03-11 13:22 ` no-reply
2020-03-11 14:50 ` Markus Armbruster
2020-03-11 15:06   ` Paolo Bonzini
2020-03-11 17:02     ` Stefan Hajnoczi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200311123624.277221-2-stefanha@redhat.com \
    --to=stefanha@redhat.com \
    --cc=alex.bennee@linaro.org \
    --cc=dgilbert@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.