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_)
105 struct nobug_flag* flag,
106 const struct nobug_context ctx);
116 struct nobug_flag* flag,
117 const struct nobug_context ctx);
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) ;
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) ;
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))
Lumiera error handling (C interface).
#define LUMIERA_DIE(err)
Abort unconditionally with a 'Fatal Error!' message.
void lumiera_lockerror_set(int err, struct nobug_flag *flag, const struct nobug_context ctx)
Translate pthread error code into lumiera error.
definitions and declarations for error-handling on low-level locking
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
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 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.
LumieraMutex lumiera_mutex_destroy(LumieraMutex self, struct nobug_flag *flag, const struct nobug_context ctx)
Destroy a mutex variable.
lumiera_mutex * LumieraMutex
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...
Mutex state handle for locked code sections.