13 #ifndef LUMIERA_MUTEX_H 14 #define LUMIERA_MUTEX_H 32 #define LUMIERA_MUTEX_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_mutex_lock (mtx, &NOBUG_FLAG(nobugflag), \ 41 &lumiera_lock_section_.rh, NOBUG_CONTEXT); \ 42 lumiera_lock_section_.lock; \ 45 LUMIERA_MUTEX_SECTION_UNLOCK; \ 56 #define LUMIERA_MUTEX_SECTION_CHAIN(nobugflag, mtx) \ 57 for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \ 58 NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \ 59 mtx, (lumiera_sectionlock_unlock_fn) lumiera_mutex_unlock \ 60 NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \ 62 if (lumiera_lock_section_.lock) \ 64 REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \ 65 lumiera_lock_section_.lock = \ 66 lumiera_mutex_lock (mtx, &NOBUG_FLAG(nobugflag), \ 67 &lumiera_lock_section_.rh, NOBUG_CONTEXT); \ 68 LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \ 70 lumiera_lock_section_.lock; \ 73 LUMIERA_MUTEX_SECTION_UNLOCK; \ 77 #define LUMIERA_MUTEX_SECTION_UNLOCK \ 78 LUMIERA_SECTION_UNLOCK_(&lumiera_lock_section_) 87 pthread_mutex_t mutex;
91 typedef lumiera_mutex* LumieraMutex;
105 struct nobug_flag* flag,
106 const struct nobug_context ctx);
116 struct nobug_flag* flag,
117 const struct nobug_context ctx);
128 static inline LumieraMutex
130 struct nobug_flag* flag,
131 struct nobug_resource_user** handle,
132 const struct nobug_context ctx)
136 NOBUG_RESOURCE_WAIT_CTX (NOBUG_FLAG_RAW(flag), self->rh,
"acquire mutex", *handle, ctx)
138 if (pthread_mutex_lock (&self->mutex))
141 NOBUG_RESOURCE_STATE_CTX (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_EXCLUSIVE, *handle, ctx) ;
156 static inline LumieraMutex
158 struct nobug_flag* flag,
159 struct nobug_resource_user** handle,
160 const struct nobug_context ctx)
164 NOBUG_RESOURCE_TRY_CTX (NOBUG_FLAG_RAW(flag), self->rh,
"try acquire mutex", *handle, ctx)
166 int err = pthread_mutex_trylock (&self->mutex);
170 NOBUG_RESOURCE_STATE_CTX (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_EXCLUSIVE, *handle, ctx) ;
174 NOBUG_RESOURCE_LEAVE_RAW_CTX (flag, *handle, ctx) ;
192 static inline LumieraMutex
194 const struct timespec* timeout,
195 struct nobug_flag* flag,
196 struct nobug_resource_user** handle,
197 const struct nobug_context ctx)
201 NOBUG_RESOURCE_TRY_CTX (NOBUG_FLAG_RAW(flag), self->rh,
"timed acquire mutex", *handle, ctx)
203 int err = pthread_mutex_timedlock (&self->mutex, timeout);
207 NOBUG_RESOURCE_STATE_CTX (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_EXCLUSIVE, *handle, ctx) ;
211 NOBUG_RESOURCE_LEAVE_RAW_CTX (flag, *handle, ctx) ;
231 struct nobug_flag* flag,
232 struct nobug_resource_user** handle,
233 const struct nobug_context ctx)
235 NOBUG_REQUIRE_CTX (
self, ctx);
237 NOBUG_RESOURCE_LEAVE_RAW_CTX (flag, *handle, ctx)
239 if (pthread_mutex_unlock (&self->mutex))
static LumieraMutex lumiera_mutex_trylock(LumieraMutex self, struct nobug_flag *flag, struct nobug_resource_user **handle, const struct nobug_context ctx)
Try to lock a mutex variable.
static void lumiera_mutex_unlock(LumieraMutex self, struct nobug_flag *flag, struct nobug_resource_user **handle, const struct nobug_context ctx)
unlock a mutex variable Never fails
Common functions for handling of time values.
definitions and declarations for error-handling on low-level locking
Lumiera error handling (C interface).
static LumieraMutex lumiera_mutex_lock(LumieraMutex self, struct nobug_flag *flag, struct nobug_resource_user **handle, const struct nobug_context ctx)
Lock a mutex variable Never fails.
#define LUMIERA_DIE(err)
Abort unconditionally with a 'Fatal Error!' message.
static LumieraMutex lumiera_mutex_timedlock(LumieraMutex self, const struct timespec *timeout, struct nobug_flag *flag, struct nobug_resource_user **handle, const struct nobug_context ctx)
Try to lock a mutex variable with a timeout.
LumieraMutex lumiera_mutex_init(LumieraMutex self, const char *purpose, struct nobug_flag *flag, const struct nobug_context ctx)
Initialise a mutex variable This initialises a 'fast' default mutex which must not be locked recursiv...
LumieraMutex lumiera_mutex_destroy(LumieraMutex self, struct nobug_flag *flag, const struct nobug_context ctx)
Destroy a mutex variable.
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.