recmutex refactoring
This commit is contained in:
parent
e7e9394f9b
commit
059f086b4f
2 changed files with 129 additions and 48 deletions
|
|
@ -42,16 +42,17 @@ lumiera_recmutex_init (LumieraRecmutex self, const char* purpose, struct nobug_f
|
|||
{
|
||||
if (self)
|
||||
{
|
||||
if (recmutexattr_once == PTHREAD_ONCE_INIT)
|
||||
pthread_once (&recmutexattr_once, recmutexattr_init);
|
||||
pthread_once (&recmutexattr_once, recmutexattr_init);
|
||||
|
||||
pthread_mutex_init (&self->recmutex, &recmutexattr);
|
||||
NOBUG_RESOURCE_HANDLE_INIT (self->rh);
|
||||
NOBUG_RESOURCE_ANNOUNCE_RAW (flag, "recmutex", purpose, self, self->rh);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
LumieraRecmutex
|
||||
lumiera_recmutex_destroy (LumieraRecmutex self, struct nobug_flag* flag)
|
||||
{
|
||||
|
|
@ -64,7 +65,6 @@ lumiera_recmutex_destroy (LumieraRecmutex self, struct nobug_flag* flag)
|
|||
return self;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Local Variables:
|
||||
// mode: C
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
#include "lib/error.h"
|
||||
#include "lib/sectionlock.h"
|
||||
#include "lib/lockerror.h"
|
||||
#include "lib/mutex.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <nobug.h>
|
||||
|
|
@ -36,46 +38,40 @@
|
|||
/**
|
||||
* Recursive Mutual exclusive section.
|
||||
*/
|
||||
#define LUMIERA_RECMUTEX_SECTION(nobugflag, mtx) \
|
||||
for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \
|
||||
lumiera_lock_section_ = { \
|
||||
mtx, lumiera_mutex_unlock_cb NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire recmutex", \
|
||||
NOBUG_RESOURCE_WAITING, lumiera_lock_section_.rh); \
|
||||
if (pthread_mutex_lock (&(mtx)->recmutex)) \
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); \
|
||||
RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_RECURSIVE, lumiera_lock_section_.rh); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_MUTEX_SECTION_UNLOCK; \
|
||||
}))
|
||||
#define LUMIERA_RECMUTEX_SECTION(nobugflag, mtx) \
|
||||
for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \
|
||||
lumiera_lock_section_ = { \
|
||||
mtx, (lumiera_sectionlock_unlock_fn) lumiera_mutex_unlock \
|
||||
NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
lumiera_lock_section_.lock = \
|
||||
lumiera_recmutex_lock (mtx, &NOBUG_FLAG(nobugflag), &lumiera_lock_section_.rh); \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_RECMUTEX_SECTION_UNLOCK; \
|
||||
}))
|
||||
|
||||
|
||||
#define LUMIERA_RECMUTEX_SECTION_CHAIN(nobugflag, mtx) \
|
||||
for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \
|
||||
NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \
|
||||
mtx, lumiera_mutex_unlock_cb NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \
|
||||
RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire recmutex", \
|
||||
NOBUG_RESOURCE_WAITING, lumiera_lock_section_.rh); \
|
||||
if (pthread_mutex_lock (&(mtx)->recmutex)) \
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); \
|
||||
RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_RECURSIVE, lumiera_lock_section_.rh); \
|
||||
LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_MUTEX_SECTION_UNLOCK; \
|
||||
}))
|
||||
#define LUMIERA_RECMUTEX_SECTION_CHAIN(nobugflag, mtx) \
|
||||
for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \
|
||||
NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \
|
||||
mtx, (lumiera_sectionlock_unlock_fn) lumiera_mutex_unlock \
|
||||
NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \
|
||||
lumiera_lock_section_.lock = \
|
||||
lumiera_recmutex_lock (mtx, &NOBUG_FLAG(nobugflag), lumiera_lock_section_.rh); \
|
||||
LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_RECMUTEX_SECTION_UNLOCK; \
|
||||
}))
|
||||
|
||||
|
||||
#define LUMIERA_RECMUTEX_SECTION_UNLOCK \
|
||||
|
|
@ -84,7 +80,7 @@
|
|||
|
||||
|
||||
/**
|
||||
* Mutex.
|
||||
* Recursive Mutex.
|
||||
*
|
||||
*/
|
||||
struct lumiera_recmutex_struct
|
||||
|
|
@ -112,12 +108,97 @@ lumiera_recmutex_init (LumieraRecmutex self, const char* purpose, struct nobug_f
|
|||
LumieraRecmutex
|
||||
lumiera_recmutex_destroy (LumieraRecmutex self, struct nobug_flag* flag);
|
||||
|
||||
/**
|
||||
* Callback for unlocking mutexes.
|
||||
* @internal
|
||||
*/
|
||||
int
|
||||
lumiera_mutex_unlock_cb (void* mutex);
|
||||
|
||||
static inline LumieraRecmutex
|
||||
lumiera_recmutex_lock (LumieraRecmutex self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
RESOURCE_WAIT (NOBUG_FLAG_RAW(flag), self->rh, "acquire mutex", *handle);
|
||||
|
||||
if (pthread_mutex_lock (&self->recmutex))
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); /* never reached (in a correct program) */
|
||||
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_RECURSIVE, *handle);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraRecmutex
|
||||
lumiera_recmutex_trylock (LumieraRecmutex self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_TRY (NOBUG_FLAG_RAW(flag), self->rh, "try acquire mutex", *handle);
|
||||
|
||||
int err = pthread_mutex_trylock (&self->recmutex);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_RECURSIVE, *handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle) /*{}*/;
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
#ifndef LUMIERA_RESTRICT
|
||||
# ifdef __cplusplus /* C++ doesnt support restrict */
|
||||
# define LUMIERA_RESTRICT
|
||||
# else
|
||||
# define LUMIERA_RESTRICT restrict
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
static inline LumieraRecmutex
|
||||
lumiera_recmutex_timedlock (LumieraRecmutex self,
|
||||
const struct timespec* LUMIERA_RESTRICT timeout,
|
||||
struct nobug_flag* flag,
|
||||
struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_TRY (NOBUG_FLAG_RAW(flag), self->rh, "timed acquire mutex", *handle);
|
||||
|
||||
int err = pthread_mutex_timedlock (&self->recmutex, timeout);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_RECURSIVE, *handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle) /*{}*/;
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
lumiera_recmutex_unlock (LumieraRecmutex self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
REQUIRE (self);
|
||||
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle)
|
||||
{
|
||||
if (pthread_mutex_unlock (&self->recmutex))
|
||||
LUMIERA_DIE (LOCK_RELEASE); /* never reached (in a correct program) */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue