add LOCKED_SECTION macros to rwlock, fix bug in rwlockacquirer

This commit is contained in:
Christian Thaeter 2008-08-07 10:45:09 +02:00
parent 12feb6e7b8
commit 47b5a2667c
2 changed files with 46 additions and 31 deletions

View file

@ -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;
}

View file

@ -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 */