13 #ifndef LUMIERA_RECMUTEX_H 14 #define LUMIERA_RECMUTEX_H 32 #define LUMIERA_RECMUTEX_SECTION(nobugflag, mtx) \ 33 for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \ 34 lumiera_lock_section_ = { \ 35 mtx, (lumiera_sectionlock_unlock_fn) lumiera_mutex_unlock \ 36 NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \ 38 if (lumiera_lock_section_.lock) \ 39 lumiera_lock_section_.lock = \ 40 lumiera_recmutex_lock (mtx, &NOBUG_FLAG(nobugflag), \ 41 &lumiera_lock_section_.rh, NOBUG_CONTEXT); \ 42 lumiera_lock_section_.lock; \ 45 LUMIERA_RECMUTEX_SECTION_UNLOCK; \ 49 #define LUMIERA_RECMUTEX_SECTION_CHAIN(nobugflag, mtx) \ 50 for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \ 51 NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \ 52 mtx, (lumiera_sectionlock_unlock_fn) lumiera_mutex_unlock \ 53 NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \ 55 if (lumiera_lock_section_.lock) \ 57 REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \ 58 lumiera_lock_section_.lock = \ 59 lumiera_recmutex_lock (mtx, &NOBUG_FLAG(nobugflag), \ 60 lumiera_lock_section_.rh, NOBUG_CONTEXT); \ 61 LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \ 63 lumiera_lock_section_.lock; \ 66 LUMIERA_RECMUTEX_SECTION_UNLOCK; \ 70 #define LUMIERA_RECMUTEX_SECTION_UNLOCK \ 71 LUMIERA_SECTION_UNLOCK_(&lumiera_lock_section_) 81 pthread_mutex_t recmutex;
85 typedef lumiera_recmutex* LumieraRecmutex;
96 struct nobug_flag* flag,
97 const struct nobug_context ctx);
106 struct nobug_flag* flag,
107 const struct nobug_context ctx);
110 static inline LumieraRecmutex
111 lumiera_recmutex_lock (LumieraRecmutex
self,
112 struct nobug_flag* flag,
113 struct nobug_resource_user** handle,
114 const struct nobug_context ctx)
118 NOBUG_RESOURCE_WAIT_CTX (NOBUG_FLAG_RAW(flag), self->rh,
"acquire mutex", *handle, ctx)
120 if (pthread_mutex_lock (&self->recmutex))
123 NOBUG_RESOURCE_STATE_CTX (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_RECURSIVE, *handle, ctx) ;
131 static inline LumieraRecmutex
132 lumiera_recmutex_trylock (LumieraRecmutex
self,
133 struct nobug_flag* flag,
134 struct nobug_resource_user** handle,
135 const struct nobug_context ctx)
139 NOBUG_RESOURCE_TRY_CTX (NOBUG_FLAG_RAW(flag), self->rh,
"try acquire mutex", *handle, ctx)
141 int err = pthread_mutex_trylock (&self->recmutex);
145 NOBUG_RESOURCE_STATE_CTX (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_RECURSIVE, *handle, ctx) ;
149 NOBUG_RESOURCE_LEAVE_RAW_CTX (flag, *handle, ctx) ;
160 static inline LumieraRecmutex
161 lumiera_recmutex_timedlock (LumieraRecmutex
self,
162 const struct timespec* timeout,
163 struct nobug_flag* flag,
164 struct nobug_resource_user** handle,
165 const struct nobug_context ctx)
169 NOBUG_RESOURCE_TRY_CTX (NOBUG_FLAG_RAW(flag), self->rh,
"timed acquire mutex", *handle, ctx)
171 int err = pthread_mutex_timedlock (&self->recmutex, timeout);
175 NOBUG_RESOURCE_STATE_CTX (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_RECURSIVE, *handle, ctx) ;
179 NOBUG_RESOURCE_LEAVE_RAW_CTX (flag, *handle, ctx) ;
191 lumiera_recmutex_unlock (LumieraRecmutex
self,
192 struct nobug_flag* flag,
193 struct nobug_resource_user** handle,
194 const struct nobug_context ctx)
196 NOBUG_REQUIRE_CTX (
self, ctx);
198 NOBUG_RESOURCE_LEAVE_RAW_CTX (flag, *handle, ctx)
200 if (pthread_mutex_unlock (&self->recmutex))
definitions and declarations for error-handling on low-level locking
LumieraRecmutex lumiera_recmutex_destroy(LumieraRecmutex self, struct nobug_flag *flag, const struct nobug_context ctx)
Destroy a recursive mutex variable.
Lumiera error handling (C interface).
#define LUMIERA_DIE(err)
Abort unconditionally with a 'Fatal Error!' message.
Mutual exclusion locking, header.
LumieraRecmutex lumiera_recmutex_init(LumieraRecmutex self, const char *purpose, struct nobug_flag *flag, const struct nobug_context ctx)
Initialise a recursive mutex variable Initialises a 'recursive' mutex which might be locked by the sa...
void lumiera_lockerror_set(int err, struct nobug_flag *flag, const struct nobug_context ctx)
Translate pthread error code into lumiera error.
Mutex state handle for locked code sections.