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_)
96 struct nobug_flag* flag,
97 const struct nobug_context ctx);
106 struct nobug_flag* flag,
107 const struct nobug_context ctx);
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) ;
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) ;
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) ;
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))
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
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...
static LumieraRecmutex lumiera_recmutex_timedlock(LumieraRecmutex self, const struct timespec *timeout, struct nobug_flag *flag, struct nobug_resource_user **handle, const struct nobug_context ctx)
LumieraRecmutex lumiera_recmutex_destroy(LumieraRecmutex self, struct nobug_flag *flag, const struct nobug_context ctx)
Destroy a recursive mutex variable.
static LumieraRecmutex lumiera_recmutex_trylock(LumieraRecmutex self, struct nobug_flag *flag, struct nobug_resource_user **handle, const struct nobug_context ctx)
static void lumiera_recmutex_unlock(LumieraRecmutex self, struct nobug_flag *flag, struct nobug_resource_user **handle, const struct nobug_context ctx)
lumiera_recmutex * LumieraRecmutex
static LumieraRecmutex lumiera_recmutex_lock(LumieraRecmutex self, struct nobug_flag *flag, struct nobug_resource_user **handle, const struct nobug_context ctx)
Mutex state handle for locked code sections.