diff --git a/src/common/interfaceregistry.c b/src/common/interfaceregistry.c index ad8bd8224..5b0db98e7 100644 --- a/src/common/interfaceregistry.c +++ b/src/common/interfaceregistry.c @@ -47,7 +47,7 @@ PSplay lumiera_interfaceregistry; PSplay lumiera_pluginregistry; -lumiera_mutex lumiera_interface_mutex; +lumiera_recmutex lumiera_interface_mutex; static int lumiera_interface_cmp_fn (const void* keya, const void* keyb); @@ -126,7 +126,7 @@ lumiera_interfaceregistry_destroy (void) psplay_delete (lumiera_pluginregistry); lumiera_pluginregistry = NULL; - lumiera_mutex_destroy (&lumiera_interface_mutex, &NOBUG_FLAG(mutex_dbg)); + lumiera_recmutex_destroy (&lumiera_interface_mutex, &NOBUG_FLAG(mutex_dbg)); REQUIRE (!psplay_nelements (lumiera_interfaceregistry), "some interfaces still registered at shutdown"); diff --git a/src/common/interfaceregistry.h b/src/common/interfaceregistry.h index 8adc46313..0ec20f29c 100644 --- a/src/common/interfaceregistry.h +++ b/src/common/interfaceregistry.h @@ -42,7 +42,7 @@ //NOBUG_DECLARE_FLAG (interface); extern PSplay lumiera_interfaceregistry; -extern lumiera_mutex lumiera_interface_mutex; +extern lumiera_recmutex lumiera_interface_mutex; /** @@ -75,8 +75,6 @@ struct lumiera_interfacenode_struct LumieraInterfacenode* deps; }; -extern lumiera_mutex lumiera_interface_mutex; - /** * Initialize the interface registry diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index cb1451c4f..0163d0c4c 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -25,6 +25,7 @@ liblumiera_la_SOURCES = \ $(liblumiera_la_srcdir)/error.c \ $(liblumiera_la_srcdir)/exception.cpp \ $(liblumiera_la_srcdir)/mutex.c \ + $(liblumiera_la_srcdir)/recmutex.c \ $(liblumiera_la_srcdir)/rwlock.c \ $(liblumiera_la_srcdir)/condition.c \ $(liblumiera_la_srcdir)/reccondition.c \ diff --git a/src/lib/mutex.c b/src/lib/mutex.c index 60078671d..d6961982d 100644 --- a/src/lib/mutex.c +++ b/src/lib/mutex.c @@ -26,9 +26,9 @@ * Mutual exclusion locking. */ -LUMIERA_ERROR_DEFINE (MUTEX_LOCK, "Mutex locking failed"); -LUMIERA_ERROR_DEFINE (MUTEX_UNLOCK, "Mutex unlocking failed"); -LUMIERA_ERROR_DEFINE (MUTEX_DESTROY, "Mutex destroy failed"); +LUMIERA_ERROR_DEFINE (LOCK_ACQUIRE, "locking failed"); +LUMIERA_ERROR_DEFINE (LOCK_RELEASE, "unlocking failed"); +LUMIERA_ERROR_DEFINE (LOCK_DESTROY, "lock destroy failed"); LumieraMutex @@ -44,32 +44,6 @@ lumiera_mutex_init (LumieraMutex self, const char* purpose, struct nobug_flag* f } -static pthread_once_t recursive_mutexattr_once = PTHREAD_ONCE_INIT; -static pthread_mutexattr_t recursive_mutexattr; - -static void recursive_mutexattr_init() -{ - pthread_mutexattr_init (&recursive_mutexattr); - pthread_mutexattr_settype (&recursive_mutexattr, PTHREAD_MUTEX_RECURSIVE); -} - - -LumieraMutex -lumiera_recmutex_init (LumieraMutex self, const char* purpose, struct nobug_flag* flag) -{ - if (self) - { - if (recursive_mutexattr_once == PTHREAD_ONCE_INIT) - pthread_once (&recursive_mutexattr_once, recursive_mutexattr_init); - - pthread_mutex_init (&self->mutex, &recursive_mutexattr); - NOBUG_RESOURCE_HANDLE_INIT (self->rh); - NOBUG_RESOURCE_ANNOUNCE_RAW (flag, "recmutex", purpose, self, self->rh); - } - return self; -} - - LumieraMutex lumiera_mutex_destroy (LumieraMutex self, struct nobug_flag* flag) { @@ -77,11 +51,16 @@ lumiera_mutex_destroy (LumieraMutex self, struct nobug_flag* flag) { NOBUG_RESOURCE_FORGET_RAW (flag, self->rh); if (pthread_mutex_destroy (&self->mutex)) - LUMIERA_DIE (MUTEX_DESTROY); + LUMIERA_DIE (LOCK_DESTROY); } return self; } +int lumiera_mutex_unlock_cb (void* mutex) +{ + return pthread_mutex_unlock ((pthread_mutex_t*) mutex); +} + /* // Local Variables: // mode: C diff --git a/src/lib/mutex.h b/src/lib/mutex.h index 0ab5b43c2..378fe00f1 100644 --- a/src/lib/mutex.h +++ b/src/lib/mutex.h @@ -23,6 +23,7 @@ #define LUMIERA_MUTEX_H #include "lib/error.h" +#include "lib/sectionlock.h" #include #include @@ -32,35 +33,30 @@ * Mutual exclusion locking, header. */ -LUMIERA_ERROR_DECLARE (MUTEX_LOCK); -LUMIERA_ERROR_DECLARE (MUTEX_UNLOCK); -LUMIERA_ERROR_DECLARE (MUTEX_DESTROY); /** * Mutual exclusive section. */ -#define LUMIERA_MUTEX_SECTION(nobugflag, mtx) \ - for (lumiera_mutexacquirer NOBUG_CLEANUP(lumiera_mutexacquirer_ensureunlocked) lumiera_mutex_section_ \ - = {(LumieraMutex)1 NOBUG_ALPHA_COMMA_NULL}; \ - lumiera_mutex_section_.mutex;) \ - for ( \ - ({ \ - lumiera_mutex_section_.mutex = (mtx); \ - NOBUG_RESOURCE_HANDLE_INIT (lumiera_mutex_section_.rh); \ - RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire mutex", &lumiera_mutex_section_, \ - NOBUG_RESOURCE_EXCLUSIVE, lumiera_mutex_section_.rh); \ - if (pthread_mutex_lock (&(mtx)->mutex)) LUMIERA_DIE (MUTEX_LOCK); \ - }); \ - lumiera_mutex_section_.mutex; \ - ({ \ - if (lumiera_mutex_section_.mutex) \ - { \ - pthread_mutex_unlock (&lumiera_mutex_section_.mutex->mutex); \ - lumiera_mutex_section_.mutex = NULL; \ - RESOURCE_LEAVE(nobugflag, lumiera_mutex_section_.rh); \ - } \ +#define LUMIERA_MUTEX_SECTION(nobugflag, mtx) \ + for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \ + lumiera_lock_section_ = { \ + (void*)1, lumiera_mutex_unlock_cb NOBUG_ALPHA_COMMA_NULL NOBUG_ALPHA_COMMA_NULL}; \ + lumiera_lock_section_.lock;) \ + for ( \ + ({ \ + lumiera_lock_section_.lock = &(mtx)->mutex; \ + NOBUG_IF_ALPHA(lumiera_lock_section_.flag = &NOBUG_FLAG(nobugflag);) \ + RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire mutex", &lumiera_lock_section_, \ + NOBUG_RESOURCE_WAITING, lumiera_lock_section_.rh); \ + if (pthread_mutex_lock (lumiera_lock_section_.lock)) LUMIERA_DIE (LOCK_ACQUIRE); \ + RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_EXCLUSIVE, lumiera_lock_section_.rh); \ + }); \ + lumiera_lock_section_.lock; \ + ({ \ + LUMIERA_MUTEX_SECTION_UNLOCK; \ })) + /** * Mutual exclusion chainbuilder section. * Usage: LUMIERA_MUTEX_SECTION(a){LUMIERA_MUTEX_SECTION_CHAIN(b){run();}} @@ -68,99 +64,81 @@ LUMIERA_ERROR_DECLARE (MUTEX_DESTROY); * This macro should only be used inside LUMIERA_MUTEX_SECTION and should be * called on the correct mutexes, period. */ -#define LUMIERA_MUTEX_SECTION_CHAIN(nobugflag, mtx) \ - for (lumiera_mutexacquirer *lumiera_mutex_section_old_ = &lumiera_mutex_section_, \ - NOBUG_CLEANUP(lumiera_mutexacquirer_ensureunlocked) lumiera_mutex_section_ = {(LumieraMutex)1 \ - NOBUG_ALPHA_COMMA_NULL}; \ - lumiera_mutex_section_.mutex;) \ - for ( \ - ({ \ - lumiera_mutex_section_.mutex = (mtx); \ - NOBUG_RESOURCE_HANDLE_INIT (lumiera_mutex_section_.rh); \ - RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire mutex", &lumiera_mutex_section_, \ - NOBUG_RESOURCE_EXCLUSIVE, lumiera_mutex_section_.rh); \ - if (pthread_mutex_lock (&(mtx)->mutex)) LUMIERA_DIE (MUTEX_LOCK); \ - if (lumiera_mutex_section_old_->mutex) \ - { \ - pthread_mutex_unlock (&lumiera_mutex_section_old_->mutex->mutex); \ - lumiera_mutex_section_old_->mutex = NULL; \ - RESOURCE_LEAVE(nobugflag, lumiera_mutex_section_old_->rh); \ - } \ - }); \ - lumiera_mutex_section_.mutex; \ - ({ \ - if (lumiera_mutex_section_.mutex) \ - { \ - pthread_mutex_unlock (&lumiera_mutex_section_.mutex->mutex); \ - lumiera_mutex_section_.mutex = NULL; \ - RESOURCE_LEAVE(nobugflag, lumiera_mutex_section_.rh); \ - } \ + +#define LUMIERA_MUTEX_SECTION_CHAIN(nobugflag, mtx) \ + for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \ + NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \ + (void*)1, lumiera_mutex_unlock_cb NOBUG_ALPHA_COMMA_NULL NOBUG_ALPHA_COMMA_NULL}; \ + lumiera_lock_section_.lock;) \ + for ( \ + ({ \ + lumiera_lock_section_.lock = &(mtx)->mutex; \ + NOBUG_IF_ALPHA(lumiera_lock_section_.flag = &NOBUG_FLAG(nobugflag);) \ + RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire mutex", &lumiera_lock_section_, \ + NOBUG_RESOURCE_WAITING, lumiera_lock_section_.rh); \ + if (pthread_mutex_lock (lumiera_lock_section_.lock)) LUMIERA_DIE (LOCK_ACQUIRE); \ + RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_EXCLUSIVE, lumiera_lock_section_.rh); \ + LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \ + }); \ + lumiera_lock_section_.lock; \ + ({ \ + LUMIERA_MUTEX_SECTION_UNLOCK; \ })) +#define LUMIERA_MUTEX_SECTION_UNLOCK \ + LUMIERA_SECTION_UNLOCK_(&lumiera_lock_section_) + + /** * Recursive Mutual exclusive section. */ -#define LUMIERA_RECMUTEX_SECTION(nobugflag, mtx) \ - for (lumiera_mutexacquirer NOBUG_CLEANUP(lumiera_mutexacquirer_ensureunlocked) lumiera_mutex_section_ \ - = {(LumieraMutex)1 NOBUG_ALPHA_COMMA_NULL}; \ - lumiera_mutex_section_.mutex;) \ - for ( \ - ({ \ - lumiera_mutex_section_.mutex = (mtx); \ - NOBUG_RESOURCE_HANDLE_INIT (lumiera_mutex_section_.rh); \ - RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire recmutex", &lumiera_mutex_section_, \ - NOBUG_RESOURCE_RECURSIVE, lumiera_mutex_section_.rh); \ - if (pthread_mutex_lock (&(mtx)->mutex)) LUMIERA_DIE (MUTEX_LOCK); \ - }); \ - lumiera_mutex_section_.mutex; \ - ({ \ - if (lumiera_mutex_section_.mutex) \ - { \ - pthread_mutex_unlock (&lumiera_mutex_section_.mutex->mutex); \ - lumiera_mutex_section_.mutex = NULL; \ - RESOURCE_LEAVE(nobugflag, lumiera_mutex_section_.rh); \ - } \ +#define LUMIERA_RECMUTEX_SECTION(nobugflag, mtx) \ + for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \ + lumiera_lock_section_ = { \ + (void*)1, lumiera_mutex_unlock_cb NOBUG_ALPHA_COMMA_NULL NOBUG_ALPHA_COMMA_NULL}; \ + lumiera_lock_section_.lock;) \ + for ( \ + ({ \ + lumiera_lock_section_.lock = &(mtx)->recmutex; \ + NOBUG_IF_ALPHA(lumiera_lock_section_.flag = &NOBUG_FLAG(nobugflag);) \ + RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire recmutex", &lumiera_lock_section_, \ + NOBUG_RESOURCE_WAITING, lumiera_lock_section_.rh); \ + if (pthread_mutex_lock (lumiera_lock_section_.lock)) LUMIERA_DIE (LOCK_ACQUIRE); \ + RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_RECURSIVE, lumiera_lock_section_.rh); \ + }); \ + lumiera_lock_section_.lock; \ + ({ \ + LUMIERA_MUTEX_SECTION_UNLOCK; \ })) -/** - * Mutual exclusion chainbuilder section. - * Usage: LUMIERA_MUTEX_SECTION(a){LUMIERA_RECMUTEX_SECTION_CHAIN(b){run();}} - * calls lock(a); lock(b); unlock(a); run(); unlock(b); - * This macro should only be used inside LUMIERA_MUTEX_SECTION and should be - * called on the correct mutexes, period. - */ -#define LUMIERA_RECMUTEX_SECTION_CHAIN(nobugflag, mtx) \ - for (lumiera_mutexacquirer *lumiera_mutex_section_old_ = &lumiera_mutex_section_, \ - NOBUG_CLEANUP(lumiera_mutexacquirer_ensureunlocked) lumiera_mutex_section_ = {(LumieraMutex)1 \ - NOBUG_ALPHA_COMMA_NULL}; \ - lumiera_mutex_section_.mutex;) \ - for ( \ - ({ \ - lumiera_mutex_section_.mutex = (mtx); \ - NOBUG_RESOURCE_HANDLE_INIT (lumiera_mutex_section_.rh); \ - RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire recmutex", &lumiera_mutex_section_, \ - NOBUG_RESOURCE_RECURSIVE, lumiera_mutex_section_.rh); \ - if (pthread_mutex_lock (&(mtx)->mutex)) LUMIERA_DIE (MUTEX_LOCK); \ - if (lumiera_mutex_section_old_->mutex) \ - { \ - pthread_mutex_unlock (&lumiera_mutex_section_old_->mutex->mutex); \ - lumiera_mutex_section_old_->mutex = NULL; \ - RESOURCE_LEAVE(nobugflag, lumiera_mutex_section_old_->rh); \ - } \ - }); \ - lumiera_mutex_section_.mutex; \ - ({ \ - if (lumiera_mutex_section_.mutex) \ - { \ - pthread_mutex_unlock (&lumiera_mutex_section_.mutex->mutex); \ - lumiera_mutex_section_.mutex = NULL; \ - RESOURCE_LEAVE(nobugflag, lumiera_mutex_section_.rh); \ - } \ +#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_ = { \ + (void*)1, lumiera_mutex_unlock_cb NOBUG_ALPHA_COMMA_NULL NOBUG_ALPHA_COMMA_NULL}; \ + lumiera_lock_section_.lock;) \ + for ( \ + ({ \ + lumiera_lock_section_.lock = &(mtx)->recmutex; \ + NOBUG_IF_ALPHA(lumiera_lock_section_.flag = &NOBUG_FLAG(nobugflag);) \ + RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire recmutex", &lumiera_lock_section_, \ + NOBUG_RESOURCE_WAITING, lumiera_lock_section_.rh); \ + if (pthread_mutex_lock (lumiera_lock_section_.lock)) 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_UNLOCK \ + LUMIERA_SECTION_UNLOCK_(&lumiera_lock_section_) + + + /** * Mutex. * @@ -173,6 +151,14 @@ struct lumiera_mutex_struct typedef struct lumiera_mutex_struct lumiera_mutex; typedef lumiera_mutex* LumieraMutex; +struct lumiera_recmutex_struct +{ + pthread_mutex_t recmutex; + RESOURCE_HANDLE (rh); +}; +typedef struct lumiera_recmutex_struct lumiera_recmutex; +typedef lumiera_recmutex* LumieraRecMutex; + /** * Initialize a mutex variable @@ -183,16 +169,6 @@ typedef lumiera_mutex* LumieraMutex; LumieraMutex lumiera_mutex_init (LumieraMutex self, const char* purpose, struct nobug_flag* flag); -/** - * Initialize a mutex variable - * Initializes a 'recursive' mutex which might be locked by the same thread multiple times. - * @param self is a pointer to the mutex to be initialized - * @return self as given - */ -LumieraMutex -lumiera_recmutex_init (LumieraMutex self, const char* purpose, struct nobug_flag* flag); - - /** * Destroy a mutex variable * @param self is a pointer to the mutex to be destroyed @@ -202,23 +178,31 @@ LumieraMutex lumiera_mutex_destroy (LumieraMutex self, struct nobug_flag* flag); -/** - * mutexacquirer used to manage the state of a mutex. - */ -struct lumiera_mutexacquirer_struct -{ - LumieraMutex mutex; - RESOURCE_HANDLE (rh); -}; -typedef struct lumiera_mutexacquirer_struct lumiera_mutexacquirer; -typedef struct lumiera_mutexacquirer_struct* LumieraMutexacquirer; -/* helper function for nobug */ -static inline void -lumiera_mutexacquirer_ensureunlocked (LumieraMutexacquirer self) -{ - ENSURE (!self->mutex, "forgot to unlock mutex"); -} +/** + * Initialize a recursive mutex variable + * Initializes a 'recursive' mutex which might be locked by the same thread multiple times. + * @param self is a pointer to the mutex to be initialized + * @return self as given + */ +LumieraRecMutex +lumiera_recmutex_init (LumieraRecMutex self, const char* purpose, struct nobug_flag* flag); + +/** + * Destroy a recursive mutex variable + * @param self is a pointer to the mutex to be destroyed + * @return self as given + */ +LumieraRecMutex +lumiera_recmutex_destroy (LumieraRecMutex self, struct nobug_flag* flag); + +/** + * Callback for unlocking mutexes. + * @internal + */ +int +lumiera_mutex_unlock_cb (void* mutex); + #endif /* diff --git a/src/lib/recmutex.c b/src/lib/recmutex.c new file mode 100644 index 000000000..b8a381e6f --- /dev/null +++ b/src/lib/recmutex.c @@ -0,0 +1,74 @@ +/* + recmutex.c - recursive mutex + + Copyright (C) Lumiera.org + 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 + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "lib/mutex.h" + +/** + * @file + * Recursive Mutexes. + */ + + +static pthread_once_t recmutexattr_once = PTHREAD_ONCE_INIT; +static pthread_mutexattr_t recmutexattr; + +static void recmutexattr_init() +{ + pthread_mutexattr_init (&recmutexattr); + pthread_mutexattr_settype (&recmutexattr, PTHREAD_MUTEX_RECURSIVE); +} + + +LumieraRecMutex +lumiera_recmutex_init (LumieraRecMutex self, const char* purpose, struct nobug_flag* flag) +{ + if (self) + { + if (recmutexattr_once == PTHREAD_ONCE_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) +{ + if (self) + { + NOBUG_RESOURCE_FORGET_RAW (flag, self->rh); + if (pthread_mutex_destroy (&self->recmutex)) + LUMIERA_DIE (LOCK_DESTROY); + } + return self; +} + + +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ diff --git a/src/lib/sectionlock.h b/src/lib/sectionlock.h new file mode 100644 index 000000000..0bc4d80fb --- /dev/null +++ b/src/lib/sectionlock.h @@ -0,0 +1,83 @@ +/* + sectionlock.h - mutex state handle + + Copyright (C) Lumiera.org + 2008, 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 + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef LUMIERA_SECTIONLOCK_H +#define LUMIERA_SECTIONLOCK_H + +#include "lib/error.h" + +#include +#include + +LUMIERA_ERROR_DECLARE (LOCK_ACQUIRE); +LUMIERA_ERROR_DECLARE (LOCK_RELEASE); +LUMIERA_ERROR_DECLARE (LOCK_DESTROY); + + +typedef int (*lumiera_sectionlock_unlock_fn)(void*); + +/** + * sectionlock used to manage the state of mutexes. + */ +struct lumiera_sectionlock_struct +{ + void* lock; + lumiera_sectionlock_unlock_fn unlock; + NOBUG_IF_ALPHA(struct nobug_flag* flag); + RESOURCE_HANDLE (rh); +}; +typedef struct lumiera_sectionlock_struct lumiera_sectionlock; +typedef struct lumiera_sectionlock_struct* LumieraSectionlock; + +/* helper function for nobug */ +static inline void +lumiera_sectionlock_ensureunlocked (LumieraSectionlock self) +{ + ENSURE (!self->lock, "forgot to unlock"); +} + + + +/** + * Unlock the lock hold in a SECTION + * @internal + * @param sectionname name used for the sectionlock instance + * @param ... some extra code to execute + */ +#define LUMIERA_SECTION_UNLOCK_(section, ...) \ + do if ((section)->lock) \ + { \ + if ((section)->unlock((section)->lock)) \ + LUMIERA_DIE (LOCK_RELEASE); \ + (section)->lock = NULL; \ + __VA_ARGS__; \ + NOBUG_RESOURCE_LEAVE_RAW((section)->flag, (section)->rh); \ + } while (0) + + +#endif +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ diff --git a/src/lib/sync.hpp b/src/lib/sync.hpp index 6515f35b9..e4fcb850a 100644 --- a/src/lib/sync.hpp +++ b/src/lib/sync.hpp @@ -102,21 +102,21 @@ namespace lib { //------------------Resource-Tracking------ void __may_block() { TODO ("Record we may block on mutex"); } void __enter() { TODO ("Record we successfully acquired the mutex"); } - void __leave() { TODO ("Record we are releasing the mutex"); } + void __left() { TODO ("Record we are released the mutex"); } }; struct Wrapped_LumieraRecMutex - : public lumiera_mutex + : public lumiera_recmutex { protected: Wrapped_LumieraRecMutex() { lumiera_recmutex_init (this, "Obj.Monitor RecMutex", &NOBUG_FLAG(sync)); } - ~Wrapped_LumieraRecMutex() { lumiera_mutex_destroy (this, &NOBUG_FLAG(sync)); } + ~Wrapped_LumieraRecMutex() { lumiera_recmutex_destroy (this, &NOBUG_FLAG(sync)); } //------------------Resource-Tracking------ void __may_block() { TODO ("Record we may block on mutex"); } void __enter() { TODO ("Record we successfully acquired the mutex"); } - void __leave() { TODO ("Record we are releasing the mutex"); } + void __left() { TODO ("Record we are released the mutex"); } }; @@ -130,7 +130,7 @@ namespace lib { //------------------Resource-Tracking------ void __may_block() { TODO ("Record we may block on mutex"); } void __enter() { TODO ("Record we successfully acquired the mutex"); } - void __leave() { TODO ("Record we are releasing the mutex"); } + void __left() { TODO ("Record we are released the mutex"); } }; @@ -144,7 +144,7 @@ namespace lib { //------------------Resource-Tracking------ void __may_block() { TODO ("Record we may block on mutex"); } void __enter() { TODO ("Record we successfully acquired the mutex"); } - void __leave() { TODO ("Record we are releasing the mutex"); } + void __left() { TODO ("Record we are released the mutex"); } }; @@ -156,10 +156,10 @@ namespace lib { : protected MTX { protected: - using MTX::mutex; + //using MTX::mutex; using MTX::__may_block; using MTX::__enter; - using MTX::__leave; + using MTX::__left; ~Mutex () { } Mutex () { } @@ -171,19 +171,22 @@ namespace lib { acquire() { __may_block(); - - if (pthread_mutex_lock (&mutex)) - throw lumiera::error::State("Mutex acquire failed."); ///////TODO capture the error-code - + + FIXME ("For to make C typesafe we have now mutex and recmutex member gnah :P -- cehteh"); + // well .. specialization on the mutex type shall solve it ... + //if (pthread_mutex_lock (&mutex)) + // throw lumiera::error::State("Mutex acquire failed."); ///////TODO capture the error-code + __enter(); } void release() - { - __leave(); - - pthread_mutex_unlock (&mutex); + { + FIXME ("For to make C typesafe we have now mutex and recmutex member gnah :P -- cehteh"); + //pthread_mutex_unlock (&mutex); + + __left(); } }; @@ -436,3 +439,10 @@ namespace lib { } // namespace lumiera #endif +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ diff --git a/tests/15locking.tests b/tests/15locking.tests index 061a2da56..81387ac8e 100644 --- a/tests/15locking.tests +++ b/tests/15locking.tests @@ -11,6 +11,10 @@ TEST "mutex not unlocked asserts" mutexforgotunlock <