diff --git a/src/lib/rwlock.c b/src/lib/rwlock.c index 71e3c9dc8..a12642c01 100644 --- a/src/lib/rwlock.c +++ b/src/lib/rwlock.c @@ -69,36 +69,32 @@ lumiera_rwlockacquirer_init (LumieraRWLockacquirer self, LumieraRWLock rwlock, e self->rwlock = rwlock; self->state = state; - switch (state) - { - case LUMIERA_RDLOCKED: - switch (pthread_rwlock_rdlock (&rwlock->rwlock)) - { - case 0: - break; - case EAGAIN: - lumiera_error_set (LUMIERA_ERROR_RWLOCK_AGAIN); - return NULL; - case EDEADLK: - lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); - return NULL; - default: - LUMIERA_DIE (RWLOCK_RLOCK); - } - case LUMIERA_WRLOCKED: - switch (pthread_rwlock_wrlock (&rwlock->rwlock)) - { - case 0: - break; - case EDEADLK: - lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); - return NULL; - default: - LUMIERA_DIE (RWLOCK_WLOCK); - } - default: - break; - } + if (state == LUMIERA_RDLOCKED) + switch (pthread_rwlock_rdlock (&rwlock->rwlock)) + { + case 0: + break; + case EAGAIN: + lumiera_error_set (LUMIERA_ERROR_RWLOCK_AGAIN); + return NULL; + case EDEADLK: + lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); + return NULL; + default: + LUMIERA_DIE (RWLOCK_RLOCK); + } + else + switch (pthread_rwlock_wrlock (&rwlock->rwlock)) + { + case 0: + break; + case EDEADLK: + lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK); + return NULL; + default: + LUMIERA_DIE (RWLOCK_WLOCK); + } + return self; } diff --git a/src/lib/rwlock.h b/src/lib/rwlock.h index c51f78076..3ac7f82ed 100644 --- a/src/lib/rwlock.h +++ b/src/lib/rwlock.h @@ -43,6 +43,25 @@ LUMIERA_ERROR_DECLARE(RWLOCK_WLOCK); * Read/write locks, header. */ +#define LUMIERA_RDLOCK_SECTION(flag, handle, rwlock) \ +RESOURCE_HANDLE (rh_##__LINE__##_); \ +lumiera_rwlockacquirer lock_##__LINE__##_; \ +RESOURCE_ENTER (flag, handle, "acquire rwlock (read)", &lock_##__LINE__##_, \ + NOBUG_RESOURCE_EXCLUSIVE, rh_##__LINE__##_); \ +for (lumiera_rwlockacquirer_init (&lock_##__LINE__##_, rwlock, LUMIERA_RDLOCKED); \ + lock_##__LINE__##_.state == LUMIERA_RDLOCKED; \ + lumiera_rwlockacquirer_unlock (&lock_##__LINE__##_), \ + ({RESOURCE_LEAVE(flag, rh_##__LINE__##_);})) + +#define LUMIERA_WRLOCK_SECTION(flag, handle, rwlock) \ +RESOURCE_HANDLE (rh_##__LINE__##_); \ +lumiera_rwlockacquirer lock_##__LINE__##_; \ +RESOURCE_ENTER (flag, handle, "acquire rwlock (write)", &lock_##__LINE__##_, \ + NOBUG_RESOURCE_EXCLUSIVE, rh_##__LINE__##_); \ +for (lumiera_rwlockacquirer_init (&lock_##__LINE__##_, rwlock, LUMIERA_WRLOCKED); \ + lock_##__LINE__##_.state == LUMIERA_WRLOCKED; \ + lumiera_rwlockacquirer_unlock (&lock_##__LINE__##_), \ + ({RESOURCE_LEAVE(flag, rh_##__LINE__##_);})) /** * RWLock. @@ -89,7 +108,7 @@ typedef struct lumiera_rwlockacquirer_struct* LumieraRWLockacquirer; static inline void lumiera_rwlockacquirer_ensureunlocked (LumieraRWLockacquirer self) { - ENSURE (self->state == LUMIERA_UNLOCKED, "forgot to unlock the rwlock mutex"); + ENSURE (self->state == LUMIERA_UNLOCKED, "forgot to unlock the rwlock"); } /* override with a macro to use the cleanup checker */