22 #ifndef LUMIERA_MUTEX_H 23 #define LUMIERA_MUTEX_H 41 #define LUMIERA_MUTEX_SECTION(nobugflag, mtx) \ 42 for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \ 43 lumiera_lock_section_ = { \ 44 mtx, (lumiera_sectionlock_unlock_fn) lumiera_mutex_unlock \ 45 NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \ 47 if (lumiera_lock_section_.lock) \ 48 lumiera_lock_section_.lock = \ 49 lumiera_mutex_lock (mtx, &NOBUG_FLAG(nobugflag), \ 50 &lumiera_lock_section_.rh, NOBUG_CONTEXT); \ 51 lumiera_lock_section_.lock; \ 54 LUMIERA_MUTEX_SECTION_UNLOCK; \ 65 #define LUMIERA_MUTEX_SECTION_CHAIN(nobugflag, mtx) \ 66 for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \ 67 NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \ 68 mtx, (lumiera_sectionlock_unlock_fn) lumiera_mutex_unlock \ 69 NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \ 71 if (lumiera_lock_section_.lock) \ 73 REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \ 74 lumiera_lock_section_.lock = \ 75 lumiera_mutex_lock (mtx, &NOBUG_FLAG(nobugflag), \ 76 &lumiera_lock_section_.rh, NOBUG_CONTEXT); \ 77 LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \ 79 lumiera_lock_section_.lock; \ 82 LUMIERA_MUTEX_SECTION_UNLOCK; \ 86 #define LUMIERA_MUTEX_SECTION_UNLOCK \ 87 LUMIERA_SECTION_UNLOCK_(&lumiera_lock_section_) 96 pthread_mutex_t mutex;
100 typedef lumiera_mutex* LumieraMutex;
114 struct nobug_flag* flag,
115 const struct nobug_context ctx);
125 struct nobug_flag* flag,
126 const struct nobug_context ctx);
137 static inline LumieraMutex
139 struct nobug_flag* flag,
140 struct nobug_resource_user** handle,
141 const struct nobug_context ctx)
145 NOBUG_RESOURCE_WAIT_CTX (NOBUG_FLAG_RAW(flag), self->rh,
"acquire mutex", *handle, ctx)
147 if (pthread_mutex_lock (&self->mutex))
150 NOBUG_RESOURCE_STATE_CTX (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_EXCLUSIVE, *handle, ctx) ;
165 static inline LumieraMutex
167 struct nobug_flag* flag,
168 struct nobug_resource_user** handle,
169 const struct nobug_context ctx)
173 NOBUG_RESOURCE_TRY_CTX (NOBUG_FLAG_RAW(flag), self->rh,
"try acquire mutex", *handle, ctx)
175 int err = pthread_mutex_trylock (&self->mutex);
179 NOBUG_RESOURCE_STATE_CTX (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_EXCLUSIVE, *handle, ctx) ;
183 NOBUG_RESOURCE_LEAVE_RAW_CTX (flag, *handle, ctx) ;
201 static inline LumieraMutex
203 const struct timespec* timeout,
204 struct nobug_flag* flag,
205 struct nobug_resource_user** handle,
206 const struct nobug_context ctx)
210 NOBUG_RESOURCE_TRY_CTX (NOBUG_FLAG_RAW(flag), self->rh,
"timed acquire mutex", *handle, ctx)
212 int err = pthread_mutex_timedlock (&self->mutex, timeout);
216 NOBUG_RESOURCE_STATE_CTX (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_EXCLUSIVE, *handle, ctx) ;
220 NOBUG_RESOURCE_LEAVE_RAW_CTX (flag, *handle, ctx) ;
240 struct nobug_flag* flag,
241 struct nobug_resource_user** handle,
242 const struct nobug_context ctx)
244 NOBUG_REQUIRE_CTX (
self, ctx);
246 NOBUG_RESOURCE_LEAVE_RAW_CTX (flag, *handle, ctx)
248 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.