On a Wednesday in 2021, Tim Wiederhake wrote:
Locks a virMutex on creation and unlocks it in its destructor. Typical usage: void function(virMutex *m) { vir_g_autoptr(virLockGuard) lock = virLockGuardNew(m);
Since the developer does not need to refer to the 'lock' variable, wrapping it in a VIR_MUTEX_LOCK macro would be more convenient. (Even though it would not be usable outside the variable declaration section, due to our enabled warnings) Jano
/* `m` is locked, and released automatically on scope exit */ ... while (expression) { vir_g_autoptr(virLockGuard) lock2 = virLockGuardNew(...); /* similar */ } } Signed-off-by: Tim Wiederhake <twiederh@xxxxxxxxxx> --- src/libvirt_private.syms | 3 +++ src/util/virthread.c | 26 ++++++++++++++++++++++++++ src/util/virthread.h | 10 ++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fa11ee3df5..d8170a59af 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3367,6 +3367,9 @@ virCondInit; virCondSignal; virCondWait; virCondWaitUntil; +virLockGuardFree; +virLockGuardNew; +virLockGuardUnlock; virMutexDestroy; virMutexInit; virMutexInitRecursive; diff --git a/src/util/virthread.c b/src/util/virthread.c index e89c1a09fb..a5a948985f 100644 --- a/src/util/virthread.c +++ b/src/util/virthread.c @@ -96,6 +96,32 @@ void virMutexUnlock(virMutex *m) pthread_mutex_unlock(&m->lock); } +virLockGuard *virLockGuardNew(virMutex *m) +{ + virLockGuard *l = g_new0(virLockGuard, 1); + l->mutex = m; + + virMutexLock(l->mutex); + return l; +} + +void virLockGuardFree(virLockGuard *l) +{ + if (!l) + return; + + virLockGuardUnlock(l); + g_free(l); +} + +void virLockGuardUnlock(virLockGuard *l) +{ + if (!l) + return; + + virMutexUnlock(g_steal_pointer(&l->mutex)); +} + int virRWLockInit(virRWLock *m) { diff --git a/src/util/virthread.h b/src/util/virthread.h index 55c8263ae6..b394dbd226 100644 --- a/src/util/virthread.h +++ b/src/util/virthread.h @@ -31,6 +31,11 @@ struct virMutex { pthread_mutex_t lock; }; +typedef struct virLockGuard virLockGuard; +struct virLockGuard { + virMutex *mutex; +}; + typedef struct virRWLock virRWLock; struct virRWLock { pthread_rwlock_t lock; @@ -121,6 +126,11 @@ void virMutexLock(virMutex *m); void virMutexUnlock(virMutex *m); +virLockGuard *virLockGuardNew(virMutex *m); +void virLockGuardFree(virLockGuard *l); +void virLockGuardUnlock(virLockGuard *l); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virLockGuard, virLockGuardFree); + int virRWLockInit(virRWLock *m) G_GNUC_WARN_UNUSED_RESULT; void virRWLockDestroy(virRWLock *m); -- 2.31.1
Attachment:
signature.asc
Description: PGP signature