Locks a virMutex on creation and unlocks it in its destructor.
The VIR_LOCK_GUARD macro is used instead of "g_auto(virLockGuard)" to
work around a clang issue (see https://bugs.llvm.org/show_bug.cgi?id=3888
and https://bugs.llvm.org/show_bug.cgi?id=43482).
Typical usage:
void function(virMutex *m)
{
VIR_LOCK_GUARD lock = virLockGuardLock(m);
/* `m` is locked, and released automatically on scope exit */
...
while (expression) {
VIR_LOCK_GUARD lock2 = virLockGuardLock(...);
/* similar */
}
}
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
virCondSignal;
virCondWait;
virCondWaitUntil;
+virLockGuardLock;
+virLockGuardUnlock;
virMutexDestroy;
virMutexInit;
virMutexInitRecursive;
pthread_mutex_unlock(&m->lock);
}
+virLockGuard virLockGuardLock(virMutex *m)
+{
+ virLockGuard l = { m };
+ virMutexLock(m);
+ return l;
+}
+
+void virLockGuardUnlock(virLockGuard *l)
+{
+ if (!l || !l->mutex)
+ return;
+
+ virMutexUnlock(g_steal_pointer(&l->mutex));
+}
+
int virRWLockInit(virRWLock *m)
{
pthread_mutex_t lock;
};
+typedef struct virLockGuard virLockGuard;
+struct virLockGuard {
+ virMutex *mutex;
+};
+
typedef struct virRWLock virRWLock;
struct virRWLock {
pthread_rwlock_t lock;
void virMutexUnlock(virMutex *m);
+virLockGuard virLockGuardLock(virMutex *m);
+void virLockGuardUnlock(virLockGuard *l);
+G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(virLockGuard, virLockGuardUnlock);
+#define VIR_LOCK_GUARD g_auto(virLockGuard) G_GNUC_UNUSED
+
int virRWLockInit(virRWLock *m) G_GNUC_WARN_UNUSED_RESULT;
void virRWLockDestroy(virRWLock *m);