diff --git a/src/lib/condition.c b/src/lib/condition.c index a7f17e57b..9db79c54f 100644 --- a/src/lib/condition.c +++ b/src/lib/condition.c @@ -2,7 +2,7 @@ condition.c - condition variable Copyright (C) Lumiera.org - 2008, Christian Thaeter + 2008, 2009 Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -26,8 +26,6 @@ * Condition variables */ -LUMIERA_ERROR_DEFINE (CONDITION_DESTROY, "condition destroy failed"); - LumieraCondition lumiera_condition_init (LumieraCondition self, const char* purpose, struct nobug_flag* flag) @@ -35,7 +33,7 @@ lumiera_condition_init (LumieraCondition self, const char* purpose, struct nobug if (self) { pthread_cond_init (&self->cond, NULL); - pthread_mutex_init (&self->mutex, NULL); + pthread_mutex_init (&self->cndmutex, NULL); NOBUG_RESOURCE_HANDLE_INIT (self->rh); NOBUG_RESOURCE_ANNOUNCE_RAW (flag, "cond_var", purpose, self, self->rh); } @@ -50,15 +48,21 @@ lumiera_condition_destroy (LumieraCondition self, struct nobug_flag* flag) { NOBUG_RESOURCE_FORGET_RAW (flag, self->rh); - if (pthread_mutex_destroy (&self->mutex)) - LUMIERA_DIE (MUTEX_DESTROY); + if (pthread_mutex_destroy (&self->cndmutex)) + LUMIERA_DIE (LOCK_DESTROY); if (pthread_cond_destroy (&self->cond)) - LUMIERA_DIE (CONDITION_DESTROY); + LUMIERA_DIE (LOCK_DESTROY); } return self; } +int lumiera_condition_unlock_cb (void* cond) +{ + return pthread_mutex_unlock (&((LumieraCondition)cond)->cndmutex); +} + + diff --git a/src/lib/condition.h b/src/lib/condition.h index 328d07c49..a2e02cebd 100644 --- a/src/lib/condition.h +++ b/src/lib/condition.h @@ -23,58 +23,73 @@ #define LUMIERA_CONDITION_H #include "lib/error.h" -#include "lib/mutex.h" +#include "lib/sectionlock.h" +#include +#include /** * @file * Condition variables, header */ -LUMIERA_ERROR_DECLARE (CONDITION_DESTROY); - - /** * Condition section. * Locks the condition mutex, one can use LUMIERA_CONDITION_WAIT to wait for signals or * LUMIERA_CONDITION_SIGNAL or LUMIERA_CONDITION_BROADCAST to wake waiting threads + * Condition variables must be at the end of locking chains, they can not be used at + * intermediate position. * @param nobugflag NoBug flag used to log actions on the condition * @param cnd Condition variable to be locked */ -#define LUMIERA_CONDITION_SECTION(nobugflag, cnd) \ - for (lumiera_conditionacquirer NOBUG_CLEANUP(lumiera_conditionacquirer_ensureunlocked) \ - lumiera_condition_section_ = {(LumieraCondition)1}; \ - lumiera_condition_section_.condition;) \ - for ( \ - ({ \ - lumiera_condition_section_.condition = (cnd); \ - NOBUG_IF(NOBUG_MODE_ALPHA, lumiera_condition_section_.flag = &NOBUG_FLAG(nobugflag)); \ - NOBUG_RESOURCE_HANDLE_INIT (lumiera_condition_section_.rh); \ - RESOURCE_ENTER (nobugflag, (cnd)->rh, "acquire condition", &lumiera_condition_section_, \ - NOBUG_RESOURCE_EXCLUSIVE, lumiera_condition_section_.rh); \ - if (pthread_mutex_lock (&(cnd)->mutex)) LUMIERA_DIE (MUTEX_LOCK); \ - }); \ - lumiera_condition_section_.condition; \ - ({ \ - LUMIERA_CONDITION_UNLOCK \ +#define LUMIERA_CONDITION_SECTION(nobugflag, cnd) \ + for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \ + lumiera_cond_section_ = { \ + (void*)1, lumiera_condition_unlock_cb NOBUG_ALPHA_COMMA_NULL NOBUG_ALPHA_COMMA_NULL}; \ + lumiera_cond_section_.lock;) \ + for ( \ + ({ \ + lumiera_cond_section_.lock = (cnd); \ + NOBUG_IF_ALPHA(lumiera_cond_section_.flag = &NOBUG_FLAG(nobugflag);) \ + RESOURCE_ENTER (nobugflag, (cnd)->rh, "acquire condmutex", &lumiera_cond_section_, \ + NOBUG_RESOURCE_WAITING, lumiera_cond_section_.rh); \ + if (pthread_mutex_lock (&(cnd)->cndmutex)) \ + LUMIERA_DIE (LOCK_ACQUIRE); \ + RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_EXCLUSIVE, lumiera_cond_section_.rh); \ + }); \ + lumiera_cond_section_.lock; \ + ({ \ + LUMIERA_CONDITION_SECTION_UNLOCK; \ })) -/** - * Explicit mutex unlock for a condition variable - * One can early unlock the mutex of a condition variable prior leaving a CONDITION_SECTION. - * The CONDITION_WAIT, CONDITION_SIGNAL and CONDITION_BROADCAST macros must not be used after the mutex - * got unlocked. - * @param nobugflag NoBug flag used to log actions on the condition - */ -#define LUMIERA_CONDITION_UNLOCK \ - if (lumiera_condition_section_.condition) \ - { \ - pthread_mutex_unlock (&lumiera_condition_section_.condition->mutex); \ - lumiera_condition_section_.condition = NULL; \ - NOBUG_RESOURCE_LEAVE_RAW(lumiera_condition_section_.flag, lumiera_condition_section_.rh); \ - } +#define LUMIERA_CONDITION_SECTION_CHAIN(nobugflag, cnd) \ + for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \ + NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_cond_section_ = { \ + (void*)1, lumiera_condition_unlock_cb NOBUG_ALPHA_COMMA_NULL NOBUG_ALPHA_COMMA_NULL}; \ + lumiera_cond_section_.lock;) \ + for ( \ + ({ \ + REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \ + lumiera_cond_section_.lock = cnd; \ + NOBUG_IF_ALPHA(lumiera_cond_section_.flag = &NOBUG_FLAG(nobugflag);) \ + RESOURCE_ENTER (nobugflag, (cnd)->rh, "acquire condmutex", &lumiera_cond_section_, \ + NOBUG_RESOURCE_WAITING, lumiera_cond_section_.rh); \ + if (pthread_mutex_lock (&(cnd)->cndmutex)) \ + LUMIERA_DIE (LOCK_ACQUIRE); \ + RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_EXCLUSIVE, lumiera_cond_section_.rh); \ + LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \ + }); \ + lumiera_cond_section_.lock; \ + ({ \ + LUMIERA_CONDITION_SECTION_UNLOCK; \ + })) + + + +#define LUMIERA_CONDITION_SECTION_UNLOCK \ + LUMIERA_SECTION_UNLOCK_(&lumiera_cond_section_) /** @@ -82,12 +97,13 @@ LUMIERA_ERROR_DECLARE (CONDITION_DESTROY); * Must be used inside a CONDITION_SECTION. * @param expr Conditon which must become true, else the condition variable goes back into sleep */ -#define LUMIERA_CONDITION_WAIT(expr) \ - do { \ - ENSURE (lumiera_condition_section_.condition, "Condition mutex not locked"); \ - NOBUG_RESOURCE_STATE_RAW (lumiera_condition_section_.flag, lumiera_condition_section_.rh, NOBUG_RESOURCE_WAITING); \ - pthread_cond_wait (&lumiera_condition_section_.condition->cond, &lumiera_condition_section_.condition->mutex); \ - NOBUG_RESOURCE_STATE_RAW (lumiera_condition_section_.flag, lumiera_condition_section_.rh, NOBUG_RESOURCE_EXCLUSIVE);\ +#define LUMIERA_CONDITION_WAIT(expr) \ + do { \ + REQUIRE (lumiera_cond_section_.lock, "Condition mutex not locked"); \ + NOBUG_RESOURCE_STATE_RAW (lumiera_cond_section_.flag, NOBUG_RESOURCE_WAITING, lumiera_cond_section_.rh); \ + pthread_cond_wait (&((LumieraCondition)lumiera_cond_section_.lock)->cond, \ + &((LumieraCondition)lumiera_cond_section_.lock)->cndmutex); \ + NOBUG_RESOURCE_STATE_RAW (lumiera_cond_section_.flag, NOBUG_RESOURCE_EXCLUSIVE, lumiera_cond_section_.rh); \ } while (!(expr)) @@ -96,12 +112,12 @@ LUMIERA_ERROR_DECLARE (CONDITION_DESTROY); * Must be used inside a CONDITION_SECTION. * Wakes one thread waiting on the condition variable */ -#define LUMIERA_CONDITION_SIGNAL \ -do { \ - ENSURE (lumiera_condition_section_.condition, "Condition mutex not locked"); \ - NOBUG_IF(NOBUG_MODE_ALPHA, TRACE(lumiera_condition_section_.flag, "Signaling")); \ - pthread_cond_signal (&lumiera_condition_section_.condition->cond); \ -} while (0) +#define LUMIERA_CONDITION_SIGNAL \ + do { \ + REQUIRE (lumiera_cond_section_.lock, "Condition mutex not locked"); \ + TRACE(NOBUG_FLAG_RAW(lumiera_cond_section_.flag), "Signal %p", &lumiera_cond_section_); \ + pthread_cond_signal (&((LumieraCondition)lumiera_cond_section_.lock)->cond); \ + } while (0) /** @@ -109,13 +125,12 @@ do { * Must be used inside a CONDITION_SECTION. * Wakes all threads waiting on the condition variable */ -#define LUMIERA_CONDITION_BROADCAST \ -do { \ - ENSURE (lumiera_condition_section_.condition, "Condition mutex not locked"); \ - NOBUG_IF(NOBUG_MODE_ALPHA, TRACE(lumiera_condition_section_.flag, "Broadcasting")); \ - pthread_cond_broadcast (&lumiera_condition_section_.condition->cond); \ -} while (0) - +#define LUMIERA_CONDITION_BROADCAST \ + do { \ + REQUIRE (lumiera_cond_section_.lock, "Condition mutex not locked"); \ + TRACE(NOBUG_FLAG_RAW(lumiera_cond_section_.flag), "Broadcast %p", &lumiera_cond_section_); \ + pthread_cond_broadcast (&((LumieraCondition)lumiera_cond_section_.lock)->cond); \ + } while (0) /** @@ -125,7 +140,7 @@ do { struct lumiera_condition_struct { pthread_cond_t cond; - pthread_mutex_t mutex; + pthread_mutex_t cndmutex; RESOURCE_HANDLE (rh); }; typedef struct lumiera_condition_struct lumiera_condition; @@ -149,26 +164,8 @@ lumiera_condition_init (LumieraCondition self, const char* purpose, struct nobug LumieraCondition lumiera_condition_destroy (LumieraCondition self, struct nobug_flag* flag); - -/** - * conditionacquirer used to manage the state of a condition variable. - */ -struct lumiera_conditionacquirer_struct -{ - LumieraCondition condition; - NOBUG_IF(NOBUG_MODE_ALPHA, struct nobug_flag* flag); - RESOURCE_HANDLE (rh); -}; -typedef struct lumiera_conditionacquirer_struct lumiera_conditionacquirer; -typedef struct lumiera_conditionacquirer_struct* LumieraConditionacquirer; - - -/* helper function for nobug */ -static inline void -lumiera_conditionacquirer_ensureunlocked (LumieraConditionacquirer self) -{ - ENSURE (!self->condition, "forgot to unlock condition variable"); -} +int +lumiera_condition_unlock_cb (void* cond); #endif diff --git a/src/lib/reccondition.c b/src/lib/reccondition.c index b70f8d179..59bc956aa 100644 --- a/src/lib/reccondition.c +++ b/src/lib/reccondition.c @@ -2,7 +2,7 @@ reccondition.c - condition variable, w/ recursive mutex Copyright (C) Lumiera.org - 2008, Christian Thaeter + 2008, 2009, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -19,7 +19,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "lib/condition.h" #include "lib/reccondition.h" /** @@ -48,7 +47,7 @@ lumiera_reccondition_init (LumieraReccondition self, const char* purpose, struct pthread_once (&recursive_mutexattr_once, recursive_mutexattr_init); pthread_cond_init (&self->cond, NULL); - pthread_mutex_init (&self->mutex, &recursive_mutexattr); + pthread_mutex_init (&self->reccndmutex, &recursive_mutexattr); NOBUG_RESOURCE_HANDLE_INIT (self->rh); NOBUG_RESOURCE_ANNOUNCE_RAW (flag, "reccond_var", purpose, self, self->rh); } @@ -63,15 +62,19 @@ lumiera_reccondition_destroy (LumieraReccondition self, struct nobug_flag* flag) { NOBUG_RESOURCE_FORGET_RAW (flag, self->rh); - if (pthread_mutex_destroy (&self->mutex)) + if (pthread_mutex_destroy (&self->reccndmutex)) LUMIERA_DIE (LOCK_DESTROY); if (pthread_cond_destroy (&self->cond)) - LUMIERA_DIE (CONDITION_DESTROY); + LUMIERA_DIE (LOCK_DESTROY); } return self; } +int lumiera_reccondition_unlock_cb (void* cond) +{ + return pthread_mutex_unlock (&((LumieraReccondition)cond)->reccndmutex); +} diff --git a/src/lib/reccondition.h b/src/lib/reccondition.h index f3246c516..aa88567d9 100644 --- a/src/lib/reccondition.h +++ b/src/lib/reccondition.h @@ -1,8 +1,8 @@ /* - reccondition.h - condition variables, w/ recursive mutex + reccondition.h - recursive locked condition variables Copyright (C) Lumiera.org - 2008, Christian Thaeter + 2008, 2009, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -23,106 +23,122 @@ #define LUMIERA_RECCONDITION_H #include "lib/error.h" -#include "lib/mutex.h" +#include "lib/sectionlock.h" +#include +#include /** * @file - * Reccondition variables. Same as Conditon variables but using a recursive mutex for locking. + * Condition variables, header */ /** - * Reccondition section. - * Locks the reccondition mutex, one can then use LUMIERA_RECCONDITION_WAIT to wait for signals or + * Recursive Condition section. + * Locks the condition mutex, one can use LUMIERA_RECCONDITION_WAIT to wait for signals or * LUMIERA_RECCONDITION_SIGNAL or LUMIERA_RECCONDITION_BROADCAST to wake waiting threads - * @param nobugflag NoBug flag used to log actions on the reccondition - * @param rcnd Reccondition variable to be locked + * @param nobugflag NoBug flag used to log actions on the condition + * @param cnd Condition variable to be locked */ -#define LUMIERA_RECCONDITION_SECTION(nobugflag, rcnd) \ - for (lumiera_recconditionacquirer NOBUG_CLEANUP(lumiera_recconditionacquirer_ensureunlocked) \ - lumiera_reccondition_section_ = {(LumieraReccondition)1}; \ - lumiera_reccondition_section_.reccondition;) \ - for ( \ - ({ \ - lumiera_reccondition_section_.reccondition = (rcnd); \ - NOBUG_IF(NOBUG_MODE_ALPHA, lumiera_reccondition_section_.flag = &NOBUG_FLAG(nobugflag)); \ - NOBUG_RESOURCE_HANDLE_INIT (lumiera_reccondition_section_.rh); \ - RESOURCE_ENTER (nobugflag, (rcnd)->rh, "acquire reccondition", &lumiera_reccondition_section_, \ - NOBUG_RESOURCE_RECURSIVE, lumiera_reccondition_section_.rh); \ - if (pthread_mutex_lock (&(rcnd)->mutex)) LUMIERA_DIE (MUTEX_LOCK); \ - }); \ - lumiera_reccondition_section_.reccondition; \ - ({ \ - LUMIERA_RECCONDITION_UNLOCK(nobugflag) \ +#define LUMIERA_RECCONDITION_SECTION(nobugflag, cnd) \ + for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \ + lumiera_reccond_section_ = { \ + (void*)1, lumiera_condition_unlock_cb NOBUG_ALPHA_COMMA_NULL NOBUG_ALPHA_COMMA_NULL}; \ + lumiera_reccond_section_.lock;) \ + for ( \ + ({ \ + lumiera_reccond_section_.lock = (cnd); \ + NOBUG_IF_ALPHA(lumiera_reccond_section_.flag = &NOBUG_FLAG(nobugflag);) \ + RESOURCE_ENTER (nobugflag, (cnd)->rh, "acquire reccondmutex", &lumiera_reccond_section_, \ + NOBUG_RESOURCE_WAITING, lumiera_reccond_section_.rh); \ + if (pthread_mutex_lock (&(cnd)->reccndmutex)) \ + LUMIERA_DIE (LOCK_ACQUIRE); \ + RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_RECURSIVE, lumiera_reccond_section_.rh); \ + }); \ + lumiera_reccond_section_.lock; \ + ({ \ + LUMIERA_RECCONDITION_SECTION_UNLOCK; \ })) -/** - * Explicit mutex unlock for a reccondition variable - * One can early unlock the mutex of a condition variable prior leaving a RECCONDITION_SECTION. - * The RECCONDITION_WAIT, RECCONDITION_SIGNAL and RECCONDITION_BROADCAST macros must not be used after the mutex - * got unlocked. - * @param nobugflag NoBug flag used to log actions on the reccondition - */ -#define LUMIERA_RECCONDITION_UNLOCK \ - if (lumiera_reccondition_section_.reccondition) \ - { \ - pthread_mutex_unlock (&lumiera_reccondition_section_.reccondition->mutex); \ - lumiera_reccondition_section_.reccondition = NULL; \ - RESOURCE_LEAVE(nobugflag, lumiera_reccondition_section_.rh); \ - } + +#define LUMIERA_RECCONDITION_SECTION_CHAIN(nobugflag, cnd) \ + for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \ + NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_reccond_section_ = { \ + (void*)1, lumiera_reccondition_unlock_cb NOBUG_ALPHA_COMMA_NULL NOBUG_ALPHA_COMMA_NULL}; \ + lumiera_reccond_section_.lock;) \ + for ( \ + ({ \ + REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \ + lumiera_reccond_section_.lock = (cnd); \ + NOBUG_IF_ALPHA(lumiera_reccond_section_.flag = &NOBUG_FLAG(nobugflag);) \ + RESOURCE_ENTER (nobugflag, (cnd)->rh, "acquire reccondmutex", &lumiera_reccond_section_, \ + NOBUG_RESOURCE_WAITING, lumiera_reccond_section_.rh); \ + if (pthread_mutex_lock (&(cnd)->reccndmutex)) \ + LUMIERA_DIE (LOCK_ACQUIRE); \ + RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_RECURSIVE, lumiera_reccond_section_.rh); \ + LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_) \ + }); \ + lumiera_reccond_section_.lock; \ + ({ \ + LUMIERA_RECCONDITION_SECTION_UNLOCK; \ + })) + + +#define LUMIERA_RECCONDITION_SECTION_UNLOCK \ + LUMIERA_SECTION_UNLOCK_(&lumiera_reccond_section_) /** - * Wait for a reccondition. + * Wait for a condition. * Must be used inside a RECCONDITION_SECTION. - * @param expr Recconditon which must become true, else the reccondition variable goes back into sleep + * @param expr Conditon which must become true, else the condition variable goes back into sleep */ -#define LUMIERA_RECCONDITION_WAIT(expr) \ - do { \ - ENSURE (lumiera_reccondition_section_.reccondition, "Reccondition mutex not locked"); \ - NOBUG_RESOURCE_STATE_RAW (lumiera_reccondition_section_.flag, lumiera_reccondition_section_.rh, NOBUG_RESOURCE_WAITING); \ - pthread_cond_wait (&lumiera_reccondition_section_.reccondition->cond, &lumiera_reccondition_section_.reccondition->mutex); \ - NOBUG_RESOURCE_STATE_RAW (lumiera_reccondition_section_.flag, lumiera_reccondition_section_.rh, NOBUG_RESOURCE_RECURSIVE); \ +#define LUMIERA_RECCONDITION_WAIT(expr) \ + do { \ + REQUIRE (lumiera_reccond_section_.lock, "Condition recmutex not locked"); \ + NOBUG_RESOURCE_STATE_RAW (lumiera_reccond_section_.flag, NOBUG_RESOURCE_WAITING, lumiera_reccond_section_.rh); \ + pthread_cond_wait (&((LumieraCondition)lumiera_reccond_section_.lock)->cond, \ + &((LumieraCondition)lumiera_reccond_section_.lock)->cndmutex); \ + NOBUG_RESOURCE_STATE_RAW (lumiera_reccond_section_.flag, NOBUG_RESOURCE_RECURSIVE, lumiera_reccond_section_.rh); \ } while (!(expr)) /** - * Signal a reccondition variable + * Signal a condition variable * Must be used inside a RECCONDITION_SECTION. * Wakes one thread waiting on the condition variable */ -#define LUMIERA_RECCONDITION_SIGNAL \ -do { \ - ENSURE (lumiera_reccondition_section_.reccondition, "Reccondition mutex not locked"); \ - NOBUG_IF(NOBUG_MODE_ALPHA, TRACE(lumiera_reccondition_section_.flag, "Signaling")); \ - pthread_cond_signal (&lumiera_reccondition_section_.reccondition->cond); \ -} while (0) +#define LUMIERA_RECCONDITION_SIGNAL \ + do { \ + REQUIRE (lumiera_reccond_section_.lock, "Condition recmutex not locked"); \ + TRACE(NOBUG_FLAG_RAW(lumiera_reccond_section_.flag), "Signal %p", &lumiera_reccond_section_); \ + pthread_cond_signal (&((LumieraCondition)lumiera_reccond_section_.lock)->cond); \ + } while (0) /** - * Broadcast a reccondition variable + * Broadcast a condition variable * Must be used inside a RECCONDITION_SECTION. - * Wakes all threads waiting on the reccondition variable + * Wakes all threads waiting on the condition variable */ -#define LUMIERA_RECCONDITION_BROADCAST \ -do { \ - ENSURE (lumiera_reccondition_section_.reccondition, "Reccondition mutex not locked"); \ - NOBUG_IF(NOBUG_MODE_ALPHA, TRACE(lumiera_reccondition_section_.flag, "Broadcasting"));\ - pthread_cond_broadcast (&lumiera_reccondition_section_.reccondition->cond); \ -} while (0) - +#define LUMIERA_RECCONDITION_BROADCAST \ + do { \ + REQUIRE (lumiera_reccond_section_.lock, "Condition recmutex not locked"); \ + TRACE(NOBUG_FLAG_RAW(lumiera_reccond_section_.flag), "Broadcast %p", &lumiera_reccond_section_); \ + pthread_cond_broadcast (&((LumieraCondition)lumiera_reccond_section_.lock)->cond); \ + } while (0) /** - * Reccondition variables. + * Condition variables. Recursive mutex variant. * */ struct lumiera_reccondition_struct { pthread_cond_t cond; - pthread_mutex_t mutex; + pthread_mutex_t reccndmutex; RESOURCE_HANDLE (rh); }; typedef struct lumiera_reccondition_struct lumiera_reccondition; @@ -130,8 +146,8 @@ typedef lumiera_reccondition* LumieraReccondition; /** - * Initialize a reccondition variable - * @param self is a pointer to the reccondition variable to be initialized + * Initialize a condition variable + * @param self is a pointer to the condition variable to be initialized * @return self as given */ LumieraReccondition @@ -139,34 +155,16 @@ lumiera_reccondition_init (LumieraReccondition self, const char* purpose, struct /** - * Destroy a reccondition variable - * @param self is a pointer to the reccondition variable to be destroyed + * Destroy a condition variable + * @param self is a pointer to the condition variable to be destroyed * @return self as given */ LumieraReccondition lumiera_reccondition_destroy (LumieraReccondition self, struct nobug_flag* flag); -/** - * recconditionacquirer used to manage the state of a reccondition variable. - */ -struct lumiera_recconditionacquirer_struct -{ - LumieraReccondition reccondition; - NOBUG_IF(NOBUG_MODE_ALPHA, struct nobug_flag* flag); - RESOURCE_HANDLE (rh); -}; -typedef struct lumiera_recconditionacquirer_struct lumiera_recconditionacquirer; -typedef struct lumiera_recconditionacquirer_struct* LumieraRecconditionacquirer; - - -/* helper function for nobug */ -static inline void -lumiera_recconditionacquirer_ensureunlocked (LumieraRecconditionacquirer self) -{ - ENSURE (!self->reccondition, "forgot to unlock reccondition variable"); -} - +int +lumiera_reccondition_unlock_cb (void* cond); #endif /* diff --git a/tests/15locking.tests b/tests/15locking.tests index 0fc57c233..0936499f2 100644 --- a/tests/15locking.tests +++ b/tests/15locking.tests @@ -70,3 +70,19 @@ PLANNED "condition broadcasting" <