Merge branch 'master' of git://git.lumiera.org/LUMIERA
This commit is contained in:
commit
a045479c63
19 changed files with 1133 additions and 376 deletions
|
|
@ -25,6 +25,7 @@ liblumiera_la_SOURCES = \
|
|||
$(liblumiera_la_srcdir)/error.c \
|
||||
$(liblumiera_la_srcdir)/mpool.c \
|
||||
$(liblumiera_la_srcdir)/exception.cpp \
|
||||
$(liblumiera_la_srcdir)/lockerror.c \
|
||||
$(liblumiera_la_srcdir)/mutex.c \
|
||||
$(liblumiera_la_srcdir)/recmutex.c \
|
||||
$(liblumiera_la_srcdir)/rwlock.c \
|
||||
|
|
@ -54,6 +55,7 @@ noinst_HEADERS += \
|
|||
$(liblumiera_la_srcdir)/error.h \
|
||||
$(liblumiera_la_srcdir)/error.hpp \
|
||||
$(liblumiera_la_srcdir)/mpool.h \
|
||||
$(liblumiera_la_srcdir)/lockerror.h \
|
||||
$(liblumiera_la_srcdir)/mutex.h \
|
||||
$(liblumiera_la_srcdir)/recmutex.h \
|
||||
$(liblumiera_la_srcdir)/rwlock.h \
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
condition.c - condition variable
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, 2009 Christian Thaeter <ct@pipapo.org>
|
||||
2008, 2009, 2010, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
|
@ -58,11 +58,10 @@ lumiera_condition_destroy (LumieraCondition self, struct nobug_flag* flag)
|
|||
}
|
||||
|
||||
|
||||
|
||||
int lumiera_condition_unlock_cb (void* cond)
|
||||
{
|
||||
return pthread_mutex_unlock (&((LumieraCondition)cond)->cndmutex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
// Local Variables:
|
||||
// mode: C
|
||||
// c-file-style: "gnu"
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
condition.h - condition variables
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
2008, 2010, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
|
@ -24,8 +24,11 @@
|
|||
|
||||
#include "lib/error.h"
|
||||
#include "lib/sectionlock.h"
|
||||
#include "lib/lockerror.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <nobug.h>
|
||||
|
||||
/**
|
||||
|
|
@ -43,49 +46,42 @@
|
|||
* @param nobugflag NoBug flag used to log actions on the condition
|
||||
* @param cnd Condition variable to be locked
|
||||
*/
|
||||
#define LUMIERA_CONDITION_SECTION(nobugflag, cnd) \
|
||||
for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \
|
||||
lumiera_cond_section_ = { \
|
||||
cnd, lumiera_condition_unlock_cb NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_cond_section_.lock) \
|
||||
{ \
|
||||
RESOURCE_WAIT (nobugflag, (cnd)->rh, "acquire condmutex", lumiera_cond_section_.rh); \
|
||||
if (pthread_mutex_lock (&(cnd)->cndmutex)) \
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); \
|
||||
RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_EXCLUSIVE, lumiera_cond_section_.rh); \
|
||||
} \
|
||||
lumiera_cond_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_CONDITION_SECTION_UNLOCK; \
|
||||
#define LUMIERA_CONDITION_SECTION(nobugflag, cnd) \
|
||||
for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \
|
||||
lumiera_lock_section_ = { \
|
||||
cnd, (lumiera_sectionlock_unlock_fn) lumiera_condition_unlock \
|
||||
NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
lumiera_lock_section_.lock = \
|
||||
lumiera_condition_lock (cnd, &NOBUG_FLAG(nobugflag), &lumiera_lock_section_.rh); \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_CONDITION_SECTION_UNLOCK; \
|
||||
}))
|
||||
|
||||
|
||||
#define LUMIERA_CONDITION_SECTION_CHAIN(nobugflag, cnd) \
|
||||
for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \
|
||||
NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_cond_section_ = { \
|
||||
cnd, lumiera_condition_unlock_cb NOBUG_ALPHA_COMMA_NULL NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_cond_section_.lock) \
|
||||
{ \
|
||||
REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \
|
||||
RESOURCE_ENTER (nobugflag, (cnd)->rh, "acquire condmutex", lumiera_cond_section_.rh); \
|
||||
if (pthread_mutex_lock (&(cnd)->cndmutex)) \
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); \
|
||||
RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_EXCLUSIVE, lumiera_cond_section_.rh); \
|
||||
LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \
|
||||
} \
|
||||
lumiera_cond_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_CONDITION_SECTION_UNLOCK; \
|
||||
#define LUMIERA_CONDITION_SECTION_CHAIN(nobugflag, cnd) \
|
||||
for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \
|
||||
NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \
|
||||
cnd, (lumiera_sectionlock_unlock_fn) lumiera_condition_unlock \
|
||||
NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \
|
||||
lumiera_lock_section_.lock = \
|
||||
lumiera_condition_lock (cnd, &NOBUG_FLAG(nobugflag), &lumiera_lock_section_.rh); \
|
||||
LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_CONDITION_SECTION_UNLOCK; \
|
||||
}))
|
||||
|
||||
|
||||
|
||||
#define LUMIERA_CONDITION_SECTION_UNLOCK \
|
||||
LUMIERA_SECTION_UNLOCK_(&lumiera_cond_section_)
|
||||
LUMIERA_SECTION_UNLOCK_(&lumiera_lock_section_)
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -93,13 +89,30 @@
|
|||
* Must be used inside a CONDITION_SECTION.
|
||||
* @param expr Conditon which must become true, else the condition variable goes back into sleep
|
||||
*/
|
||||
#define LUMIERA_CONDITION_WAIT(expr) \
|
||||
do { \
|
||||
REQUIRE (lumiera_cond_section_.lock, "Condition mutex not locked"); \
|
||||
NOBUG_RESOURCE_STATE_RAW (lumiera_cond_section_.flag, NOBUG_RESOURCE_WAITING, lumiera_cond_section_.rh); \
|
||||
pthread_cond_wait (&((LumieraCondition)lumiera_cond_section_.lock)->cond, \
|
||||
&((LumieraCondition)lumiera_cond_section_.lock)->cndmutex); \
|
||||
NOBUG_RESOURCE_STATE_RAW (lumiera_cond_section_.flag, NOBUG_RESOURCE_EXCLUSIVE, lumiera_cond_section_.rh); \
|
||||
#define LUMIERA_CONDITION_WAIT(expr) \
|
||||
do { \
|
||||
REQUIRE (lumiera_lock_section_.lock, "Condition mutex not locked"); \
|
||||
lumiera_condition_wait (lumiera_lock_section_.lock, \
|
||||
lumiera_lock_section_.flag, \
|
||||
&lumiera_lock_section_.rh); \
|
||||
} while (!(expr))
|
||||
|
||||
|
||||
/**
|
||||
* Timed wait for a condition.
|
||||
* Must be used inside a CONDITION_SECTION.
|
||||
* @param expr Conditon which must become true, else the condition variable goes back into sleep
|
||||
* @param timeout time when the wait expired
|
||||
* sets LUMIERA_ERROR_LOCK_TIMEOUT when the timeout passed
|
||||
*/
|
||||
#define LUMIERA_CONDITION_TIMEDWAIT(expr, timeout) \
|
||||
do { \
|
||||
REQUIRE (lumiera_lock_section_.lock, "Condition mutex not locked"); \
|
||||
if (!lumiera_condition_timedwait (lumiera_lock_section_.lock, \
|
||||
timeout, \
|
||||
lumiera_lock_section_.flag, \
|
||||
&lumiera_lock_section_.rh)) \
|
||||
break; \
|
||||
} while (!(expr))
|
||||
|
||||
|
||||
|
|
@ -108,11 +121,11 @@
|
|||
* Must be used inside a CONDITION_SECTION.
|
||||
* Wakes one thread waiting on the condition variable
|
||||
*/
|
||||
#define LUMIERA_CONDITION_SIGNAL \
|
||||
do { \
|
||||
REQUIRE (lumiera_cond_section_.lock, "Condition mutex not locked"); \
|
||||
TRACE(NOBUG_FLAG_RAW(lumiera_cond_section_.flag), "Signal %p", &lumiera_cond_section_); \
|
||||
pthread_cond_signal (&((LumieraCondition)lumiera_cond_section_.lock)->cond); \
|
||||
#define LUMIERA_CONDITION_SIGNAL \
|
||||
do { \
|
||||
REQUIRE (lumiera_cond_section_.lock, "Condition mutex not locked"); \
|
||||
lumiera_condition_signal (lumiera_lock_section_.lock, \
|
||||
lumiera_lock_section_.flag); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
|
@ -121,11 +134,11 @@
|
|||
* Must be used inside a CONDITION_SECTION.
|
||||
* Wakes all threads waiting on the condition variable
|
||||
*/
|
||||
#define LUMIERA_CONDITION_BROADCAST \
|
||||
do { \
|
||||
REQUIRE (lumiera_cond_section_.lock, "Condition mutex not locked"); \
|
||||
TRACE(NOBUG_FLAG_RAW(lumiera_cond_section_.flag), "Broadcast %p", &lumiera_cond_section_); \
|
||||
pthread_cond_broadcast (&((LumieraCondition)lumiera_cond_section_.lock)->cond); \
|
||||
#define LUMIERA_CONDITION_BROADCAST \
|
||||
do { \
|
||||
REQUIRE (lumiera_cond_section_.lock, "Condition mutex not locked"); \
|
||||
lumiera_condition_broadcast (lumiera_lock_section_.lock, \
|
||||
lumiera_lock_section_.flag); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
|
@ -160,8 +173,148 @@ lumiera_condition_init (LumieraCondition self, const char* purpose, struct nobug
|
|||
LumieraCondition
|
||||
lumiera_condition_destroy (LumieraCondition self, struct nobug_flag* flag);
|
||||
|
||||
int
|
||||
lumiera_condition_unlock_cb (void* cond);
|
||||
|
||||
static inline LumieraCondition
|
||||
lumiera_condition_lock (LumieraCondition self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
RESOURCE_WAIT (NOBUG_FLAG_RAW(flag), self->rh, "acquire condvar", *handle);
|
||||
|
||||
if (pthread_mutex_lock (&self->cndmutex))
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); /* never reached (in a correct program) */
|
||||
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_EXCLUSIVE, *handle);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraCondition
|
||||
lumiera_condition_trylock (LumieraCondition self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_TRY (NOBUG_FLAG_RAW(flag), self->rh, "try acquire condvar", *handle);
|
||||
|
||||
int err = pthread_mutex_trylock (&self->cndmutex);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_EXCLUSIVE, *handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle) /*{}*/;
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraCondition
|
||||
lumiera_condition_timedlock (LumieraCondition self,
|
||||
const struct timespec* timeout,
|
||||
struct nobug_flag* flag,
|
||||
struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_TRY (NOBUG_FLAG_RAW(flag), self->rh, "timed acquire condvar", *handle);
|
||||
|
||||
int err = pthread_mutex_timedlock (&self->cndmutex, timeout);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_EXCLUSIVE, *handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle) /*{}*/;
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraCondition
|
||||
lumiera_condition_wait (LumieraCondition self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_STATE_RAW (flag, NOBUG_RESOURCE_WAITING, *handle);
|
||||
|
||||
pthread_cond_wait (&self->cond, &self->cndmutex);
|
||||
|
||||
NOBUG_RESOURCE_STATE_RAW (flag, NOBUG_RESOURCE_EXCLUSIVE, *handle);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraCondition
|
||||
lumiera_condition_timedwait (LumieraCondition self,
|
||||
const struct timespec* timeout,
|
||||
struct nobug_flag* flag,
|
||||
struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_STATE_RAW (flag, NOBUG_RESOURCE_WAITING, *handle);
|
||||
|
||||
int err;
|
||||
do {
|
||||
err = pthread_cond_timedwait (&self->cond, &self->cndmutex, timeout);
|
||||
} while(err == EINTR);
|
||||
|
||||
NOBUG_RESOURCE_STATE_RAW (flag, NOBUG_RESOURCE_EXCLUSIVE, *handle);
|
||||
|
||||
if (err)
|
||||
{
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline void
|
||||
lumiera_condition_signal (LumieraCondition self, struct nobug_flag* flag)
|
||||
{
|
||||
TRACE(NOBUG_FLAG_RAW(flag), "Signal %p", self);
|
||||
pthread_cond_signal (&self->cond);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
lumiera_condition_broadcast (LumieraCondition self, struct nobug_flag* flag)
|
||||
{
|
||||
TRACE(NOBUG_FLAG_RAW(flag), "Broadcast %p", self);
|
||||
pthread_cond_broadcast (&self->cond);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
lumiera_condition_unlock (LumieraCondition self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
REQUIRE(self);
|
||||
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle)
|
||||
{
|
||||
if (pthread_mutex_unlock (&self->cndmutex))
|
||||
LUMIERA_DIE (LOCK_RELEASE); /* never reached (in a correct program) */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
*/
|
||||
LUMIERA_ERROR_DEFINE (ERRNO, "errno");
|
||||
LUMIERA_ERROR_DEFINE (EERROR, "could not initialize error system");
|
||||
LUMIERA_ERROR_DEFINE (UNKNOWN, "unknown error");
|
||||
|
||||
|
||||
/* Thread local storage */
|
||||
|
|
|
|||
|
|
@ -164,6 +164,7 @@ lumiera_error_peek (void);
|
|||
predefined errors
|
||||
*/
|
||||
LUMIERA_ERROR_DECLARE (ERRNO);
|
||||
LUMIERA_ERROR_DECLARE (UNKNOWN);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
|||
79
src/lib/lockerror.c
Normal file
79
src/lib/lockerror.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
lockerror.c - error declarations for all locks (mutex, rwlocks, cond vars)
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2010, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "lib/lockerror.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* fatal errors (EINVAL usually) */
|
||||
LUMIERA_ERROR_DEFINE (LOCK_ACQUIRE, "locking failed");
|
||||
LUMIERA_ERROR_DEFINE (LOCK_RELEASE, "unlocking failed");
|
||||
LUMIERA_ERROR_DEFINE (LOCK_DESTROY, "lock destroy failed");
|
||||
|
||||
/* runtime errors */
|
||||
LUMIERA_ERROR_DEFINE (LOCK_INVAL, "lock initialization error");
|
||||
LUMIERA_ERROR_DEFINE (LOCK_BUSY, "already locked");
|
||||
LUMIERA_ERROR_DEFINE (LOCK_DEADLK, "already locked by this thread");
|
||||
LUMIERA_ERROR_DEFINE (LOCK_PERM, "not locked by this thread");
|
||||
LUMIERA_ERROR_DEFINE (LOCK_TIMEOUT, "timeout");
|
||||
LUMIERA_ERROR_DEFINE (LOCK_AGAIN, "too much recursive locks");
|
||||
|
||||
|
||||
|
||||
void
|
||||
lumiera_lockerror_set (int err, struct nobug_flag* flag, const char* extra)
|
||||
{
|
||||
switch (err)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EINVAL:
|
||||
LUMIERA_ERROR_SET_ALERT(NOBUG_FLAG_RAW(flag), LOCK_INVAL, extra);
|
||||
break;
|
||||
case EBUSY:
|
||||
LUMIERA_ERROR_SET(NOBUG_FLAG_RAW(flag), LOCK_BUSY, extra);
|
||||
break;
|
||||
case EDEADLK:
|
||||
LUMIERA_ERROR_SET(NOBUG_FLAG_RAW(flag), LOCK_DEADLK, extra);
|
||||
break;
|
||||
case EPERM:
|
||||
LUMIERA_ERROR_SET_ALERT(NOBUG_FLAG_RAW(flag), LOCK_PERM, extra);
|
||||
break;
|
||||
case ETIMEDOUT:
|
||||
LUMIERA_ERROR_SET(NOBUG_FLAG_RAW(flag), LOCK_TIMEOUT, extra);
|
||||
break;
|
||||
case EAGAIN:
|
||||
LUMIERA_ERROR_SET_WARNING(NOBUG_FLAG_RAW(flag), LOCK_AGAIN, extra);
|
||||
break;
|
||||
default:
|
||||
LUMIERA_ERROR_SET_CRITICAL(NOBUG_FLAG_RAW(flag), UNKNOWN, extra);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Local Variables:
|
||||
// mode: C
|
||||
// c-file-style: "gnu"
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
*/
|
||||
53
src/lib/lockerror.h
Normal file
53
src/lib/lockerror.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
lockerror.h - error declarations for all locks (mutex, rwlocks, cond vars)
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2010, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef LUMIERA_LOCKERRORS_H
|
||||
#define LUMIERA_LOCKERRORS_H
|
||||
|
||||
#include "lib/error.h"
|
||||
|
||||
/* fatal errors (EINVAL usually), we DIE on these, shall never ever happen on a correct program */
|
||||
LUMIERA_ERROR_DECLARE (LOCK_ACQUIRE);
|
||||
LUMIERA_ERROR_DECLARE (LOCK_RELEASE);
|
||||
LUMIERA_ERROR_DECLARE (LOCK_DESTROY);
|
||||
|
||||
/* runtime errors */
|
||||
LUMIERA_ERROR_DECLARE (LOCK_INVAL);
|
||||
LUMIERA_ERROR_DECLARE (LOCK_BUSY);
|
||||
LUMIERA_ERROR_DECLARE (LOCK_DEADLK);
|
||||
LUMIERA_ERROR_DECLARE (LOCK_PERM);
|
||||
LUMIERA_ERROR_DECLARE (LOCK_TIMEOUT);
|
||||
LUMIERA_ERROR_DECLARE (LOCK_AGAIN);
|
||||
|
||||
/**
|
||||
* Translate pthread error code into lumiera error
|
||||
*/
|
||||
void
|
||||
lumiera_lockerror_set (int err, struct nobug_flag* flag, const char* extra);
|
||||
|
||||
#endif
|
||||
/*
|
||||
// Local Variables:
|
||||
// mode: C
|
||||
// c-file-style: "gnu"
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
*/
|
||||
|
|
@ -26,11 +26,6 @@
|
|||
* Mutual exclusion locking.
|
||||
*/
|
||||
|
||||
LUMIERA_ERROR_DEFINE (LOCK_ACQUIRE, "locking failed");
|
||||
LUMIERA_ERROR_DEFINE (LOCK_RELEASE, "unlocking failed");
|
||||
LUMIERA_ERROR_DEFINE (LOCK_DESTROY, "lock destroy failed");
|
||||
|
||||
|
||||
LumieraMutex
|
||||
lumiera_mutex_init (LumieraMutex self, const char* purpose, struct nobug_flag* flag)
|
||||
{
|
||||
|
|
@ -56,10 +51,7 @@ lumiera_mutex_destroy (LumieraMutex self, struct nobug_flag* flag)
|
|||
return self;
|
||||
}
|
||||
|
||||
int lumiera_mutex_unlock_cb (void* mutex)
|
||||
{
|
||||
return pthread_mutex_unlock (&((LumieraMutex)mutex)->mutex);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Local Variables:
|
||||
|
|
|
|||
183
src/lib/mutex.h
183
src/lib/mutex.h
|
|
@ -24,8 +24,10 @@
|
|||
|
||||
#include "lib/error.h"
|
||||
#include "lib/sectionlock.h"
|
||||
#include "lib/lockerror.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <nobug.h>
|
||||
|
||||
/**
|
||||
|
|
@ -33,26 +35,22 @@
|
|||
* Mutual exclusion locking, header.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Mutual exclusive section.
|
||||
*/
|
||||
#define LUMIERA_MUTEX_SECTION(nobugflag, mtx) \
|
||||
for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \
|
||||
lumiera_lock_section_ = { \
|
||||
mtx, lumiera_mutex_unlock_cb NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
RESOURCE_WAIT (nobugflag, (mtx)->rh, "acquire mutex", lumiera_lock_section_.rh); \
|
||||
if (pthread_mutex_lock (&(mtx)->mutex)) \
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); \
|
||||
RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_EXCLUSIVE, lumiera_lock_section_.rh); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_MUTEX_SECTION_UNLOCK; \
|
||||
#define LUMIERA_MUTEX_SECTION(nobugflag, mtx) \
|
||||
for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \
|
||||
lumiera_lock_section_ = { \
|
||||
mtx, (lumiera_sectionlock_unlock_fn) lumiera_mutex_unlock \
|
||||
NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
lumiera_lock_section_.lock = \
|
||||
lumiera_mutex_lock (mtx, &NOBUG_FLAG(nobugflag), &lumiera_lock_section_.rh); \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_MUTEX_SECTION_UNLOCK; \
|
||||
}))
|
||||
|
||||
|
||||
|
|
@ -63,26 +61,26 @@
|
|||
* This macro should only be used inside LUMIERA_MUTEX_SECTION and should be
|
||||
* called on the correct mutexes, period.
|
||||
*/
|
||||
#define LUMIERA_MUTEX_SECTION_CHAIN(nobugflag, mtx) \
|
||||
for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \
|
||||
NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \
|
||||
mtx, lumiera_mutex_unlock_cb NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \
|
||||
RESOURCE_WAIT (nobugflag, (mtx)->rh, "acquire mutex", lumiera_lock_section_.rh); \
|
||||
if (pthread_mutex_lock (&(mtx)->mutex)) \
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); \
|
||||
RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_EXCLUSIVE, lumiera_lock_section_.rh); \
|
||||
LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_MUTEX_SECTION_UNLOCK; \
|
||||
#define LUMIERA_MUTEX_SECTION_CHAIN(nobugflag, mtx) \
|
||||
for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \
|
||||
NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \
|
||||
mtx, (lumiera_sectionlock_unlock_fn) lumiera_mutex_unlock \
|
||||
NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \
|
||||
lumiera_lock_section_.lock = \
|
||||
lumiera_mutex_lock (mtx, &NOBUG_FLAG(nobugflag), &lumiera_lock_section_.rh); \
|
||||
LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_MUTEX_SECTION_UNLOCK; \
|
||||
}))
|
||||
|
||||
|
||||
#define LUMIERA_MUTEX_SECTION_UNLOCK \
|
||||
LUMIERA_SECTION_UNLOCK_(&lumiera_lock_section_)
|
||||
|
||||
|
|
@ -104,6 +102,8 @@ typedef lumiera_mutex* LumieraMutex;
|
|||
* Initialize a mutex variable
|
||||
* This initializes a 'fast' default mutex which must not be locked recursively from one thread.
|
||||
* @param self is a pointer to the mutex to be initialized
|
||||
* @param purpose textual hint for the nobug resourcetracker
|
||||
* @param flag nobug logging target
|
||||
* @return self as given
|
||||
*/
|
||||
LumieraMutex
|
||||
|
|
@ -112,6 +112,7 @@ lumiera_mutex_init (LumieraMutex self, const char* purpose, struct nobug_flag* f
|
|||
/**
|
||||
* Destroy a mutex variable
|
||||
* @param self is a pointer to the mutex to be destroyed
|
||||
* @param flag nobug logging target
|
||||
* @return self as given
|
||||
*/
|
||||
LumieraMutex
|
||||
|
|
@ -119,11 +120,115 @@ lumiera_mutex_destroy (LumieraMutex self, struct nobug_flag* flag);
|
|||
|
||||
|
||||
/**
|
||||
* Callback for unlocking mutexes.
|
||||
* @internal
|
||||
* Lock a mutex variable
|
||||
* Never fails
|
||||
* @param self is a pointer to the mutex to be destroyed
|
||||
* @param flag nobug logging target
|
||||
* @param handle pointer to nobug user handle (NULL in beta and release builds)
|
||||
* @return self as given
|
||||
*/
|
||||
int
|
||||
lumiera_mutex_unlock_cb (void* mutex);
|
||||
static inline LumieraMutex
|
||||
lumiera_mutex_lock (LumieraMutex self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
RESOURCE_WAIT (NOBUG_FLAG_RAW(flag), self->rh, "acquire mutex", *handle);
|
||||
|
||||
if (pthread_mutex_lock (&self->mutex))
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); /* never reached (in a correct program) */
|
||||
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_EXCLUSIVE, *handle);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to lock a mutex variable
|
||||
* @param self is a pointer to the mutex to be destroyed
|
||||
* @param flag nobug logging target
|
||||
* @param handle pointer to nobug user handle (NULL in beta and release builds)
|
||||
* @return self as given or NULL on error, lumiera_error gets set approbiately
|
||||
*/
|
||||
static inline LumieraMutex
|
||||
lumiera_mutex_trylock (LumieraMutex self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_TRY (NOBUG_FLAG_RAW(flag), self->rh, "try acquire mutex", *handle);
|
||||
|
||||
int err = pthread_mutex_trylock (&self->mutex);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_EXCLUSIVE, *handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle) /*{}*/;
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to lock a mutex variable with a timeout
|
||||
* @param self is a pointer to the mutex to be destroyed
|
||||
* @param timeout timeout for waiting for the lock
|
||||
* @param flag nobug logging target
|
||||
* @param handle pointer to nobug user handle (NULL in beta and release builds)
|
||||
* @return self as given or NULL on error, lumiera_error gets set approbiately
|
||||
*/
|
||||
static inline LumieraMutex
|
||||
lumiera_mutex_timedlock (LumieraMutex self,
|
||||
const struct timespec* timeout,
|
||||
struct nobug_flag* flag,
|
||||
struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_TRY (NOBUG_FLAG_RAW(flag), self->rh, "timed acquire mutex", *handle);
|
||||
|
||||
int err = pthread_mutex_timedlock (&self->mutex, timeout);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_EXCLUSIVE, *handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle) /*{}*/;
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* unlock a mutex variable
|
||||
* Never fails
|
||||
* @param self is a pointer to the mutex to be destroyed
|
||||
* @param flag nobug logging target
|
||||
* @param handle pointer to nobug user handle (NULL in beta and release builds)
|
||||
*/
|
||||
static inline void
|
||||
lumiera_mutex_unlock (LumieraMutex self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
REQUIRE(self);
|
||||
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle)
|
||||
{
|
||||
if (pthread_mutex_unlock (&self->mutex))
|
||||
LUMIERA_DIE (LOCK_RELEASE); /* never reached (in a correct program) */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -72,9 +72,10 @@ lumiera_reccondition_destroy (LumieraReccondition self, struct nobug_flag* flag)
|
|||
}
|
||||
|
||||
|
||||
|
||||
int lumiera_reccondition_unlock_cb (void* cond)
|
||||
{
|
||||
return pthread_mutex_unlock (&((LumieraReccondition)cond)->reccndmutex);
|
||||
}
|
||||
|
||||
/*
|
||||
// Local Variables:
|
||||
// mode: C
|
||||
// c-file-style: "gnu"
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
reccondition.h - recursive locked condition variables
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, 2009, Christian Thaeter <ct@pipapo.org>
|
||||
2008, 2009, 2010, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
|
|
@ -24,8 +24,11 @@
|
|||
|
||||
#include "lib/error.h"
|
||||
#include "lib/sectionlock.h"
|
||||
#include "lib/lockerror.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <nobug.h>
|
||||
|
||||
/**
|
||||
|
|
@ -41,49 +44,43 @@
|
|||
* @param nobugflag NoBug flag used to log actions on the condition
|
||||
* @param cnd Condition variable to be locked
|
||||
*/
|
||||
#define LUMIERA_RECCONDITION_SECTION(nobugflag, cnd) \
|
||||
for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \
|
||||
lumiera_reccond_section_ = { \
|
||||
cnd, lumiera_reccondition_unlock_cb NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_reccond_section_.lock) \
|
||||
{ \
|
||||
RESOURCE_WAIT (nobugflag, (cnd)->rh, "acquire reccondmutex", lumiera_reccond_section_.rh); \
|
||||
if (pthread_mutex_lock (&(cnd)->reccndmutex)) \
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); \
|
||||
RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_RECURSIVE, lumiera_reccond_section_.rh); \
|
||||
} \
|
||||
lumiera_reccond_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_RECCONDITION_SECTION_UNLOCK; \
|
||||
#define LUMIERA_RECCONDITION_SECTION(nobugflag, cnd) \
|
||||
for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \
|
||||
lumiera_lock_section_ = { \
|
||||
cnd, (lumiera_sectionlock_unlock_fn) lumiera_reccondition_unlock \
|
||||
NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
lumiera_lock_section_.lock = \
|
||||
lumiera_reccondition_lock (cnd, &NOBUG_FLAG(nobugflag), &lumiera_lock_section_.rh); \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_RECCONDITION_SECTION_UNLOCK; \
|
||||
}))
|
||||
|
||||
|
||||
|
||||
#define LUMIERA_RECCONDITION_SECTION_CHAIN(nobugflag, cnd) \
|
||||
for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \
|
||||
NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_reccond_section_ = { \
|
||||
cnd, lumiera_reccondition_unlock_cb NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_reccond_section_.lock) \
|
||||
{ \
|
||||
REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \
|
||||
RESOURCE_WAIT (nobugflag, (cnd)->rh, "acquire reccondmutex", lumiera_reccond_section_.rh); \
|
||||
if (pthread_mutex_lock (&(cnd)->reccndmutex)) \
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); \
|
||||
RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_RECURSIVE, lumiera_reccond_section_.rh); \
|
||||
LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \
|
||||
} \
|
||||
lumiera_reccond_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_RECCONDITION_SECTION_UNLOCK; \
|
||||
#define LUMIERA_RECCONDITION_SECTION_CHAIN(nobugflag, cnd) \
|
||||
for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \
|
||||
NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \
|
||||
cnd, (lumiera_sectionlock_unlock_fn) lumiera_reccondition_unlock \
|
||||
NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \
|
||||
lumiera_lock_section_.lock = \
|
||||
lumiera_reccondition_lock (cnd, &NOBUG_FLAG(nobugflag), &lumiera_lock_section_.rh); \
|
||||
LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_RECCONDITION_SECTION_UNLOCK; \
|
||||
}))
|
||||
|
||||
|
||||
#define LUMIERA_RECCONDITION_SECTION_UNLOCK \
|
||||
LUMIERA_SECTION_UNLOCK_(&lumiera_reccond_section_)
|
||||
LUMIERA_SECTION_UNLOCK_(&lumiera_lock_section_)
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -91,26 +88,45 @@
|
|||
* Must be used inside a RECCONDITION_SECTION.
|
||||
* @param expr Condition which must become true, else the condition variable goes back into sleep
|
||||
*/
|
||||
#define LUMIERA_RECCONDITION_WAIT(expr) \
|
||||
do { \
|
||||
REQUIRE (lumiera_reccond_section_.lock, "Condition recmutex not locked"); \
|
||||
NOBUG_RESOURCE_STATE_RAW (lumiera_reccond_section_.flag, NOBUG_RESOURCE_WAITING, lumiera_reccond_section_.rh); \
|
||||
pthread_cond_wait (&((LumieraReccondition)lumiera_reccond_section_.lock)->cond, \
|
||||
&((LumieraReccondition)lumiera_reccond_section_.lock)->reccndmutex); \
|
||||
NOBUG_RESOURCE_STATE_RAW (lumiera_reccond_section_.flag, NOBUG_RESOURCE_RECURSIVE, lumiera_reccond_section_.rh); \
|
||||
#define LUMIERA_RECCONDITION_WAIT(expr) \
|
||||
do { \
|
||||
REQUIRE (lumiera_lock_section_.lock, "Reccondition mutex not locked"); \
|
||||
lumiera_reccondition_wait (lumiera_lock_section_.lock, \
|
||||
NOBUG_FLAG_RAW(lumiera_lock_section_.flag), \
|
||||
&lumiera_lock_section_.rh); \
|
||||
} while (!(expr))
|
||||
|
||||
|
||||
/**
|
||||
* Timed wait for a condition.
|
||||
* Must be used inside a RECCONDITION_SECTION.
|
||||
* @param expr Recconditon which must become true, else the condition variable goes back into sleep
|
||||
* @param timeout time when the wait expired
|
||||
* sets LUMIERA_ERROR_LOCK_TIMEOUT when the timeout passed
|
||||
*/
|
||||
#define LUMIERA_RECCONDITION_TIMEDWAIT(expr, timeout) \
|
||||
do { \
|
||||
REQUIRE (lumiera_lock_section_.lock, "Reccondition mutex not locked"); \
|
||||
if (!lumiera_reccondition_timedwait (lumiera_lock_section_.lock, \
|
||||
timeout, \
|
||||
lumiera_lock_section_.flag, \
|
||||
&lumiera_lock_section_.rh)) \
|
||||
break; \
|
||||
} while (!(expr))
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Signal a condition variable
|
||||
* Must be used inside a RECCONDITION_SECTION.
|
||||
* Wakes one thread waiting on the condition variable
|
||||
*/
|
||||
#define LUMIERA_RECCONDITION_SIGNAL \
|
||||
do { \
|
||||
REQUIRE (lumiera_reccond_section_.lock, "Condition recmutex not locked"); \
|
||||
TRACE(NOBUG_FLAG_RAW(lumiera_reccond_section_.flag), "Signal %p", &lumiera_reccond_section_); \
|
||||
pthread_cond_signal (&((LumieraReccondition)lumiera_reccond_section_.lock)->cond); \
|
||||
#define LUMIERA_RECCONDITION_SIGNAL \
|
||||
do { \
|
||||
REQUIRE (lumiera_lock_section_.lock, "Reccondition mutex not locked"); \
|
||||
lumiera_reccondition_signal (lumiera_lock_section_.lock, \
|
||||
lumiera_lock_section_.flag); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
|
@ -119,11 +135,11 @@
|
|||
* Must be used inside a RECCONDITION_SECTION.
|
||||
* Wakes all threads waiting on the condition variable
|
||||
*/
|
||||
#define LUMIERA_RECCONDITION_BROADCAST \
|
||||
do { \
|
||||
REQUIRE (lumiera_reccond_section_.lock, "Condition recmutex not locked"); \
|
||||
TRACE(NOBUG_FLAG_RAW(lumiera_reccond_section_.flag), "Broadcast %p", &lumiera_reccond_section_); \
|
||||
pthread_cond_broadcast (&((LumieraReccondition)lumiera_reccond_section_.lock)->cond); \
|
||||
#define LUMIERA_RECCONDITION_BROADCAST \
|
||||
do { \
|
||||
REQUIRE (lumiera_lock_section_.lock, "Reccondition mutex not locked"); \
|
||||
lumiera_reccondition_broadcast (lumiera_lock_section_.lock, \
|
||||
lumiera_lock_section_.flag); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
|
@ -159,8 +175,149 @@ LumieraReccondition
|
|||
lumiera_reccondition_destroy (LumieraReccondition self, struct nobug_flag* flag);
|
||||
|
||||
|
||||
int
|
||||
lumiera_reccondition_unlock_cb (void* cond);
|
||||
|
||||
static inline LumieraReccondition
|
||||
lumiera_reccondition_lock (LumieraReccondition self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
RESOURCE_WAIT (NOBUG_FLAG_RAW(flag), self->rh, "acquire reccondvar", *handle);
|
||||
|
||||
if (pthread_mutex_lock (&self->reccndmutex))
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); /* never reached (in a correct program) */
|
||||
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_RECURSIVE, *handle);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraReccondition
|
||||
lumiera_reccondition_trylock (LumieraReccondition self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_TRY (NOBUG_FLAG_RAW(flag), self->rh, "try acquire reccondvar", *handle);
|
||||
|
||||
int err = pthread_mutex_trylock (&self->reccndmutex);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_RECURSIVE, *handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle) /*{}*/;
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraReccondition
|
||||
lumiera_reccondition_timedlock (LumieraReccondition self,
|
||||
const struct timespec* timeout,
|
||||
struct nobug_flag* flag,
|
||||
struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_TRY (NOBUG_FLAG_RAW(flag), self->rh, "timed acquire reccondvar", *handle);
|
||||
|
||||
int err = pthread_mutex_timedlock (&self->reccndmutex, timeout);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_RECURSIVE, *handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle) /*{}*/;
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraReccondition
|
||||
lumiera_reccondition_wait (LumieraReccondition self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_STATE_RAW (flag, NOBUG_RESOURCE_WAITING, *handle);
|
||||
|
||||
pthread_cond_wait (&self->cond, &self->reccndmutex);
|
||||
|
||||
NOBUG_RESOURCE_STATE_RAW (flag, NOBUG_RESOURCE_RECURSIVE, *handle);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraReccondition
|
||||
lumiera_reccondition_timedwait (LumieraReccondition self,
|
||||
const struct timespec* timeout,
|
||||
struct nobug_flag* flag,
|
||||
struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_STATE_RAW (flag, NOBUG_RESOURCE_WAITING, *handle);
|
||||
|
||||
int err;
|
||||
do {
|
||||
err = pthread_cond_timedwait (&self->cond, &self->reccndmutex, timeout);
|
||||
} while(err == EINTR);
|
||||
|
||||
NOBUG_RESOURCE_STATE_RAW (flag, NOBUG_RESOURCE_RECURSIVE, *handle);
|
||||
|
||||
if (err)
|
||||
{
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline void
|
||||
lumiera_reccondition_signal (LumieraReccondition self, struct nobug_flag* flag)
|
||||
{
|
||||
TRACE(NOBUG_FLAG_RAW(flag), "Signal %p", self);
|
||||
pthread_cond_signal (&self->cond);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
lumiera_reccondition_broadcast (LumieraReccondition self, struct nobug_flag* flag)
|
||||
{
|
||||
TRACE(NOBUG_FLAG_RAW(flag), "Broadcast %p", self);
|
||||
pthread_cond_broadcast (&self->cond);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
lumiera_reccondition_unlock (LumieraReccondition self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
REQUIRE(self);
|
||||
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle)
|
||||
{
|
||||
if (pthread_mutex_unlock (&self->reccndmutex))
|
||||
LUMIERA_DIE (LOCK_RELEASE); /* never reached (in a correct program) */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -42,16 +42,17 @@ lumiera_recmutex_init (LumieraRecmutex self, const char* purpose, struct nobug_f
|
|||
{
|
||||
if (self)
|
||||
{
|
||||
if (recmutexattr_once == PTHREAD_ONCE_INIT)
|
||||
pthread_once (&recmutexattr_once, recmutexattr_init);
|
||||
pthread_once (&recmutexattr_once, recmutexattr_init);
|
||||
|
||||
pthread_mutex_init (&self->recmutex, &recmutexattr);
|
||||
NOBUG_RESOURCE_HANDLE_INIT (self->rh);
|
||||
NOBUG_RESOURCE_ANNOUNCE_RAW (flag, "recmutex", purpose, self, self->rh);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
LumieraRecmutex
|
||||
lumiera_recmutex_destroy (LumieraRecmutex self, struct nobug_flag* flag)
|
||||
{
|
||||
|
|
@ -64,7 +65,6 @@ lumiera_recmutex_destroy (LumieraRecmutex self, struct nobug_flag* flag)
|
|||
return self;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Local Variables:
|
||||
// mode: C
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
#include "lib/error.h"
|
||||
#include "lib/sectionlock.h"
|
||||
#include "lib/lockerror.h"
|
||||
#include "lib/mutex.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <nobug.h>
|
||||
|
|
@ -36,46 +38,40 @@
|
|||
/**
|
||||
* Recursive Mutual exclusive section.
|
||||
*/
|
||||
#define LUMIERA_RECMUTEX_SECTION(nobugflag, mtx) \
|
||||
for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \
|
||||
lumiera_lock_section_ = { \
|
||||
mtx, lumiera_mutex_unlock_cb NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire recmutex", \
|
||||
NOBUG_RESOURCE_WAITING, lumiera_lock_section_.rh); \
|
||||
if (pthread_mutex_lock (&(mtx)->recmutex)) \
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); \
|
||||
RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_RECURSIVE, lumiera_lock_section_.rh); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_MUTEX_SECTION_UNLOCK; \
|
||||
}))
|
||||
#define LUMIERA_RECMUTEX_SECTION(nobugflag, mtx) \
|
||||
for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \
|
||||
lumiera_lock_section_ = { \
|
||||
mtx, (lumiera_sectionlock_unlock_fn) lumiera_mutex_unlock \
|
||||
NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
lumiera_lock_section_.lock = \
|
||||
lumiera_recmutex_lock (mtx, &NOBUG_FLAG(nobugflag), &lumiera_lock_section_.rh); \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_RECMUTEX_SECTION_UNLOCK; \
|
||||
}))
|
||||
|
||||
|
||||
#define LUMIERA_RECMUTEX_SECTION_CHAIN(nobugflag, mtx) \
|
||||
for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \
|
||||
NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \
|
||||
mtx, lumiera_mutex_unlock_cb NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \
|
||||
RESOURCE_ENTER (nobugflag, (mtx)->rh, "acquire recmutex", \
|
||||
NOBUG_RESOURCE_WAITING, lumiera_lock_section_.rh); \
|
||||
if (pthread_mutex_lock (&(mtx)->recmutex)) \
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); \
|
||||
RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_RECURSIVE, lumiera_lock_section_.rh); \
|
||||
LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_MUTEX_SECTION_UNLOCK; \
|
||||
}))
|
||||
#define LUMIERA_RECMUTEX_SECTION_CHAIN(nobugflag, mtx) \
|
||||
for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \
|
||||
NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \
|
||||
mtx, (lumiera_sectionlock_unlock_fn) lumiera_mutex_unlock \
|
||||
NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \
|
||||
lumiera_lock_section_.lock = \
|
||||
lumiera_recmutex_lock (mtx, &NOBUG_FLAG(nobugflag), lumiera_lock_section_.rh); \
|
||||
LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_RECMUTEX_SECTION_UNLOCK; \
|
||||
}))
|
||||
|
||||
|
||||
#define LUMIERA_RECMUTEX_SECTION_UNLOCK \
|
||||
|
|
@ -84,7 +80,7 @@
|
|||
|
||||
|
||||
/**
|
||||
* Mutex.
|
||||
* Recursive Mutex.
|
||||
*
|
||||
*/
|
||||
struct lumiera_recmutex_struct
|
||||
|
|
@ -112,12 +108,88 @@ lumiera_recmutex_init (LumieraRecmutex self, const char* purpose, struct nobug_f
|
|||
LumieraRecmutex
|
||||
lumiera_recmutex_destroy (LumieraRecmutex self, struct nobug_flag* flag);
|
||||
|
||||
/**
|
||||
* Callback for unlocking mutexes.
|
||||
* @internal
|
||||
*/
|
||||
int
|
||||
lumiera_mutex_unlock_cb (void* mutex);
|
||||
|
||||
static inline LumieraRecmutex
|
||||
lumiera_recmutex_lock (LumieraRecmutex self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
RESOURCE_WAIT (NOBUG_FLAG_RAW(flag), self->rh, "acquire mutex", *handle);
|
||||
|
||||
if (pthread_mutex_lock (&self->recmutex))
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); /* never reached (in a correct program) */
|
||||
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_RECURSIVE, *handle);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraRecmutex
|
||||
lumiera_recmutex_trylock (LumieraRecmutex self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_TRY (NOBUG_FLAG_RAW(flag), self->rh, "try acquire mutex", *handle);
|
||||
|
||||
int err = pthread_mutex_trylock (&self->recmutex);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_RECURSIVE, *handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle) /*{}*/;
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraRecmutex
|
||||
lumiera_recmutex_timedlock (LumieraRecmutex self,
|
||||
const struct timespec* timeout,
|
||||
struct nobug_flag* flag,
|
||||
struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_TRY (NOBUG_FLAG_RAW(flag), self->rh, "timed acquire mutex", *handle);
|
||||
|
||||
int err = pthread_mutex_timedlock (&self->recmutex, timeout);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_RECURSIVE, *handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle) /*{}*/;
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
lumiera_recmutex_unlock (LumieraRecmutex self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
REQUIRE (self);
|
||||
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle)
|
||||
{
|
||||
if (pthread_mutex_unlock (&self->recmutex))
|
||||
LUMIERA_DIE (LOCK_RELEASE); /* never reached (in a correct program) */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -23,13 +23,6 @@
|
|||
#include "lib/rwlock.h"
|
||||
|
||||
|
||||
LUMIERA_ERROR_DEFINE(RWLOCK_AGAIN, "maximum number of readlocks exceed");
|
||||
LUMIERA_ERROR_DEFINE(RWLOCK_DEADLOCK, "deadlock detected");
|
||||
LUMIERA_ERROR_DEFINE(RWLOCK_DESTROY, "destroying rwlock");
|
||||
LUMIERA_ERROR_DEFINE(RWLOCK_UNLOCK, "unlock rwlock failed");
|
||||
LUMIERA_ERROR_DEFINE(RWLOCK_RDLOCK, "locking rwlock for reading failed");
|
||||
LUMIERA_ERROR_DEFINE(RWLOCK_WRLOCK, "locking rwlock for writing failed");
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Read/write locks.
|
||||
|
|
@ -55,17 +48,12 @@ lumiera_rwlock_destroy (LumieraRWLock self, struct nobug_flag* flag)
|
|||
{
|
||||
NOBUG_RESOURCE_FORGET_RAW (flag, self->rh);
|
||||
if (pthread_rwlock_destroy (&self->rwlock))
|
||||
LUMIERA_DIE (RWLOCK_DESTROY);
|
||||
LUMIERA_DIE (LOCK_DESTROY);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
int lumiera_rwlock_unlock_cb (void* rwlock)
|
||||
{
|
||||
return pthread_rwlock_unlock (&((LumieraRWLock)rwlock)->rwlock);
|
||||
}
|
||||
|
||||
/*
|
||||
// Local Variables:
|
||||
// mode: C
|
||||
|
|
|
|||
301
src/lib/rwlock.h
301
src/lib/rwlock.h
|
|
@ -26,15 +26,13 @@
|
|||
#error "This header must be included with _GNU_SOURCE or _POSIX_C_SOURCE >= 200112L defined"
|
||||
#endif
|
||||
|
||||
#include "lib/sectionlock.h"
|
||||
#include "lib/lockerror.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <nobug.h>
|
||||
|
||||
LUMIERA_ERROR_DECLARE(RWLOCK_AGAIN);
|
||||
LUMIERA_ERROR_DECLARE(RWLOCK_DEADLOCK);
|
||||
LUMIERA_ERROR_DECLARE(RWLOCK_DESTROY);
|
||||
LUMIERA_ERROR_DECLARE(RWLOCK_UNLOCK);
|
||||
LUMIERA_ERROR_DECLARE(RWLOCK_RDLOCK);
|
||||
LUMIERA_ERROR_DECLARE(RWLOCK_WRLOCK);
|
||||
|
||||
/**
|
||||
* @file
|
||||
|
|
@ -44,44 +42,41 @@ LUMIERA_ERROR_DECLARE(RWLOCK_WRLOCK);
|
|||
|
||||
/**
|
||||
* Read locked section.
|
||||
* readlocks may fail when there are too much readers, one has to check the error afterwards!
|
||||
*/
|
||||
#define LUMIERA_RDLOCK_SECTION(nobugflag, rwlck) \
|
||||
for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \
|
||||
lumiera_lock_section_ = { \
|
||||
rwlck, lumiera_rwlock_unlock_cb NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
RESOURCE_WAIT (nobugflag, (rwlck)->rh, "acquire readlock", lumiera_lock_section_.rh); \
|
||||
if (pthread_rwlock_rdlock (&(rwlck)->rwlock)) \
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); \
|
||||
RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_SHARED, lumiera_lock_section_.rh); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_RWLOCK_SECTION_UNLOCK; \
|
||||
#define LUMIERA_RDLOCK_SECTION(nobugflag, rwlck) \
|
||||
for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \
|
||||
lumiera_lock_section_ = { \
|
||||
rwlck, (lumiera_sectionlock_unlock_fn) lumiera_rwlock_unlock \
|
||||
NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
lumiera_lock_section_.lock = \
|
||||
lumiera_rwlock_rdlock (rwlck, &NOBUG_FLAG(nobugflag), &lumiera_lock_section_.rh); \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_RWLOCK_SECTION_UNLOCK; \
|
||||
}))
|
||||
|
||||
|
||||
#define LUMIERA_RDLOCK_SECTION_CHAIN(nobugflag, rwlck) \
|
||||
for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \
|
||||
NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \
|
||||
rwlck, lumiera_rwlock_unlock_cb NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \
|
||||
RESOURCE_WAIT (nobugflag, (rwlck)->rh, "acquire readlock", lumiera_lock_section_.rh); \
|
||||
if (pthread_rwlock_rdlock (&(rwlck)->rwlock)) \
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); \
|
||||
RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_SHARED, lumiera_lock_section_.rh); \
|
||||
LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_MUTEX_SECTION_UNLOCK; \
|
||||
#define LUMIERA_RDLOCK_SECTION_CHAIN(nobugflag, rwlck) \
|
||||
for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \
|
||||
NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \
|
||||
rwlck, (lumiera_sectionlock_unlock_fn) lumiera_rwlock_unlock \
|
||||
NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \
|
||||
lumiera_lock_section_.lock = \
|
||||
lumiera_rwlock_rdlock (rwlck, &NOBUG_FLAG(nobugflag), lumiera_lock_section_.rh); \
|
||||
LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_RWLOCK_SECTION_UNLOCK; \
|
||||
}))
|
||||
|
||||
|
||||
|
|
@ -89,43 +84,39 @@ LUMIERA_ERROR_DECLARE(RWLOCK_WRLOCK);
|
|||
/**
|
||||
* Write locked section.
|
||||
*/
|
||||
#define LUMIERA_WRLOCK_SECTION(nobugflag, rwlck) \
|
||||
for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \
|
||||
lumiera_lock_section_ = { \
|
||||
rwlck, lumiera_rwlock_unlock_cb NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
RESOURCE_WAIT (nobugflag, (rwlck)->rh, "acquire writelock", lumiera_lock_section_.rh); \
|
||||
if (pthread_rwlock_wrlock (&(rwlck)->rwlock)) \
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); \
|
||||
RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_EXCLUSIVE, lumiera_lock_section_.rh); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_RWLOCK_SECTION_UNLOCK; \
|
||||
#define LUMIERA_WRLOCK_SECTION(nobugflag, rwlck) \
|
||||
for (lumiera_sectionlock NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) \
|
||||
lumiera_lock_section_ = { \
|
||||
rwlck, (lumiera_sectionlock_unlock_fn) lumiera_rwlock_unlock \
|
||||
NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
lumiera_lock_section_.lock = \
|
||||
lumiera_rwlock_wrlock (rwlck, &NOBUG_FLAG(nobugflag), &lumiera_lock_section_.rh); \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_RWLOCK_SECTION_UNLOCK; \
|
||||
}))
|
||||
|
||||
|
||||
#define LUMIERA_WRLOCK_SECTION_CHAIN(nobugflag, rwlck) \
|
||||
for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \
|
||||
NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \
|
||||
rwlck, lumiera_rwlock_unlock_cb NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \
|
||||
RESOURCE_WAIT (nobugflag, (rwlck)->rh, "acquire writelock", lumiera_lock_section_.rh); \
|
||||
if (pthread_rwlock_wrlock (&(twlck)->rwlock)) \
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); \
|
||||
RESOURCE_STATE (nobugflag, NOBUG_RESOURCE_EXCLUSIVE, lumiera_lock_section_.rh); \
|
||||
LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_MUTEX_SECTION_UNLOCK; \
|
||||
#define LUMIERA_WRLOCK_SECTION_CHAIN(nobugflag, rwlck) \
|
||||
for (lumiera_sectionlock *lumiera_lock_section_old_ = &lumiera_lock_section_, \
|
||||
NOBUG_CLEANUP(lumiera_sectionlock_ensureunlocked) lumiera_lock_section_ = { \
|
||||
rwlck, (lumiera_sectionlock_unlock_fn) lumiera_rwlock_unlock \
|
||||
NOBUG_ALPHA_COMMA(&NOBUG_FLAG(nobugflag)) NOBUG_ALPHA_COMMA_NULL}; \
|
||||
({ \
|
||||
if (lumiera_lock_section_.lock) \
|
||||
{ \
|
||||
REQUIRE (lumiera_lock_section_old_->lock, "section prematurely unlocked"); \
|
||||
lumiera_lock_section_.lock = \
|
||||
lumiera_rwlock_wrlock (rwlck, &NOBUG_FLAG(nobugflag), lumiera_lock_section_.rh); \
|
||||
LUMIERA_SECTION_UNLOCK_(lumiera_lock_section_old_); \
|
||||
} \
|
||||
lumiera_lock_section_.lock; \
|
||||
}); \
|
||||
({ \
|
||||
LUMIERA_RWLOCK_SECTION_UNLOCK; \
|
||||
}))
|
||||
|
||||
|
||||
|
|
@ -161,9 +152,167 @@ lumiera_rwlock_init (LumieraRWLock self, const char* purpose, struct nobug_flag*
|
|||
LumieraRWLock
|
||||
lumiera_rwlock_destroy (LumieraRWLock self, struct nobug_flag* flag);
|
||||
|
||||
static inline LumieraRWLock
|
||||
lumiera_rwlock_rdlock (LumieraRWLock self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
RESOURCE_WAIT (NOBUG_FLAG_RAW(flag), self->rh, "acquire rwlock for reading", *handle);
|
||||
|
||||
int err = pthread_rwlock_rdlock (&self->rwlock);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_SHARED, *handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle) /*{}*/;
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraRWLock
|
||||
lumiera_rwlock_tryrdlock (LumieraRWLock self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_TRY (NOBUG_FLAG_RAW(flag), self->rh, "try acquire rwlock for reading", *handle);
|
||||
|
||||
int err = pthread_rwlock_tryrdlock (&self->rwlock);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_SHARED, *handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle) /*{}*/;
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraRWLock
|
||||
lumiera_rwlock_timedrdlock (LumieraRWLock self,
|
||||
const struct timespec* timeout,
|
||||
struct nobug_flag* flag,
|
||||
struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_TRY (NOBUG_FLAG_RAW(flag), self->rh, "timed acquire rwlock for reading", *handle);
|
||||
|
||||
int err = pthread_rwlock_timedrdlock (&self->rwlock, timeout);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_SHARED, *handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle) /*{}*/;
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraRWLock
|
||||
lumiera_rwlock_wrlock (LumieraRWLock self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
RESOURCE_WAIT (NOBUG_FLAG_RAW(flag), self->rh, "acquire rwlock for writing", *handle);
|
||||
|
||||
if (pthread_rwlock_wrlock (&self->rwlock))
|
||||
LUMIERA_DIE (LOCK_ACQUIRE); /* never reached (in a correct program) */
|
||||
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_EXCLUSIVE, *handle);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraRWLock
|
||||
lumiera_rwlock_trywrlock (LumieraRWLock self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_TRY (NOBUG_FLAG_RAW(flag), self->rh, "try acquire rwlock for writing", *handle);
|
||||
|
||||
int err = pthread_rwlock_trywrlock (&self->rwlock);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_EXCLUSIVE, *handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle) /*{}*/;
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline LumieraRWLock
|
||||
lumiera_rwlock_timedwrlock (LumieraRWLock self,
|
||||
const struct timespec* timeout,
|
||||
struct nobug_flag* flag,
|
||||
struct nobug_resource_user** handle)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
NOBUG_RESOURCE_TRY (NOBUG_FLAG_RAW(flag), self->rh, "timed acquire rwlock for writing", *handle);
|
||||
|
||||
int err = pthread_rwlock_timedwrlock (&self->rwlock, timeout);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
RESOURCE_STATE (NOBUG_FLAG_RAW(flag), NOBUG_RESOURCE_EXCLUSIVE, *handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle) /*{}*/;
|
||||
lumiera_lockerror_set (err, flag, __func__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
lumiera_rwlock_unlock (LumieraRWLock self, struct nobug_flag* flag, struct nobug_resource_user** handle)
|
||||
{
|
||||
REQUIRE(self);
|
||||
|
||||
NOBUG_RESOURCE_LEAVE_RAW(flag, *handle)
|
||||
{
|
||||
if (pthread_rwlock_unlock (&self->rwlock))
|
||||
LUMIERA_DIE (LOCK_RELEASE); /* never reached (in a correct program) */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lumiera_rwlock_unlock_cb (void* rwlock);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,17 +22,11 @@
|
|||
#ifndef LUMIERA_SECTIONLOCK_H
|
||||
#define LUMIERA_SECTIONLOCK_H
|
||||
|
||||
#include "lib/error.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <nobug.h>
|
||||
|
||||
LUMIERA_ERROR_DECLARE (LOCK_ACQUIRE);
|
||||
LUMIERA_ERROR_DECLARE (LOCK_RELEASE);
|
||||
LUMIERA_ERROR_DECLARE (LOCK_DESTROY);
|
||||
|
||||
|
||||
typedef int (*lumiera_sectionlock_unlock_fn)(void*);
|
||||
typedef int (*lumiera_sectionlock_unlock_fn)(void*, struct nobug_flag* flag, struct nobug_resource_user** handle);
|
||||
|
||||
/**
|
||||
* sectionlock used to manage the state of mutexes.
|
||||
|
|
@ -55,22 +49,17 @@ lumiera_sectionlock_ensureunlocked (LumieraSectionlock self)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Unlock the lock hold in a SECTION
|
||||
* @internal
|
||||
* @param sectionname name used for the sectionlock instance
|
||||
* @param ... some extra code to execute
|
||||
*/
|
||||
#define LUMIERA_SECTION_UNLOCK_(section) \
|
||||
do if ((section)->lock) \
|
||||
{ \
|
||||
NOBUG_RESOURCE_LEAVE_RAW((section)->flag, (section)->rh) \
|
||||
{ \
|
||||
if ((section)->unlock((section)->lock)) \
|
||||
LUMIERA_DIE (LOCK_RELEASE); \
|
||||
(section)->lock = NULL; \
|
||||
} \
|
||||
#define LUMIERA_SECTION_UNLOCK_(section) \
|
||||
do if ((section)->lock) \
|
||||
{ \
|
||||
(section)->unlock((section)->lock, (section)->flag, &(section)->rh); \
|
||||
(section)->lock = NULL; \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ liblumiprocmobjectsession_la_SOURCES = \
|
|||
$(liblumiprocmobjectsession_la_srcdir)/mobjectfactory.cpp \
|
||||
$(liblumiprocmobjectsession_la_srcdir)/placement-index.cpp \
|
||||
$(liblumiprocmobjectsession_la_srcdir)/query-resolver.cpp \
|
||||
$(liblumiprocmobjectsession_la_srcdir)/query-focus.cpp \
|
||||
$(liblumiprocmobjectsession_la_srcdir)/placement-index-query-resolver.cpp \
|
||||
$(liblumiprocmobjectsession_la_srcdir)/session-services.cpp \
|
||||
$(liblumiprocmobjectsession_la_srcdir)/root.cpp \
|
||||
|
|
|
|||
|
|
@ -33,59 +33,67 @@ test_components_LDADD = \
|
|||
liblumiera.la \
|
||||
$(NOBUGMT_LUMIERA_LIBS) -ldl -lboost_program_options-mt -lboost_regex-mt
|
||||
|
||||
test_components_SOURCES = \
|
||||
$(testcomponents_srcdir)/backend/mediaaccessmock.cpp \
|
||||
$(testcomponents_srcdir)/backend/mediaaccessmocktest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/assetcategorytest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/compoundmediatest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/deleteassettest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/identityofassetstest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/mediastructurequerytest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/basicpipetest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/createassettest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/dependent-assets-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/makecliptest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/orderingofassetstest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/testasset.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-basic-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-argument-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-equality-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-mutation-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-clone-builder-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-use1-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-use2-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-use3-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-binding-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-registry-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/test-dummy-commands.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/argument-tuple-accept-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/memento-tie-test.cpp \
|
||||
test_components_SOURCES = \
|
||||
$(testcomponents_srcdir)/backend/mediaaccessmock.cpp \
|
||||
$(testcomponents_srcdir)/backend/mediaaccessmocktest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/assetcategorytest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/compoundmediatest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/deleteassettest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/identityofassetstest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/mediastructurequerytest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/basicpipetest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/createassettest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/dependent-assets-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/makecliptest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/orderingofassetstest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/testasset.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-basic-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-argument-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-equality-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-mutation-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-clone-builder-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-use1-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-use2-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-use3-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-binding-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-registry-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/test-dummy-commands.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/argument-tuple-accept-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/memento-tie-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/handling-pattern-basics-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/handling-pattern-standard-impl-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/engine/buff-table-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/engine/node-basic-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/engine/node-fabrication-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/engine/node-operation-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/engine/node-source-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/builder/buildertooltest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/builder/buildsegmenttest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/controller/rendersegmenttest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/mobject-ref-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/placement-basic-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/placement-hierarchy-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/placement-ref-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/engine/buff-table-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/engine/node-basic-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/engine/node-fabrication-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/engine/node-operation-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/engine/node-source-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/builder/buildertooltest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/builder/buildsegmenttest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/controller/rendersegmenttest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/mobject-ref-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/placement-basic-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/placement-hierarchy-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/placement-ref-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/test-scopes.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/placement-index-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/addcliptest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/deletecliptest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/rebuildfixturetest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/sessionmanagertest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/testclip.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/defsmanagerimpltest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/defsmanagertest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/defsregistryimpltest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/sessionstructuretest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/addcliptest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/deletecliptest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/rebuildfixturetest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/sessionmanagertest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/testclip.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/defsmanagerimpltest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/defsmanagertest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/defsregistryimpltest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/sessionstructuretest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/scope-query-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/placement-index-query-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/query-focus-stack-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/query-resolver-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/query-focus-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/session-service-access-test.cpp \
|
||||
$(testcomponents_srcdir)/mainsuite.cpp
|
||||
|
||||
|
||||
noinst_HEADERS += \
|
||||
$(testcomponents_srcdir)/backend/mediaaccessmock.hpp \
|
||||
$(testcomponents_srcdir)/proc/asset/testclipasset.hpp \
|
||||
|
|
|
|||
|
|
@ -46,11 +46,16 @@ test_lib_SOURCES = \
|
|||
$(testlib_srcdir)/factorytest.cpp \
|
||||
$(testlib_srcdir)/format-helper-test.cpp \
|
||||
$(testlib_srcdir)/functor-util-test.cpp \
|
||||
$(testlib_srcdir)/util-foreach-test.cpp \
|
||||
$(testlib_srcdir)/hash-indexed-test.cpp \
|
||||
$(testlib_srcdir)/helloworldtest.cpp \
|
||||
$(testlib_srcdir)/lifecycletest.cpp \
|
||||
$(testlib_srcdir)/multifact-test.cpp \
|
||||
$(testlib_srcdir)/multifact-argument-test.cpp \
|
||||
$(testlib_srcdir)/iter-adapter-test.cpp \
|
||||
$(testlib_srcdir)/item-wrapper-test.cpp \
|
||||
$(testlib_srcdir)/itertools-test.cpp \
|
||||
$(testlib_srcdir)/iter-source-test.cpp \
|
||||
$(testlib_srcdir)/meta/typelist-test.cpp \
|
||||
$(testlib_srcdir)/meta/typelist-manip-test.cpp \
|
||||
$(testlib_srcdir)/meta/typeseq-manip-test.cpp \
|
||||
|
|
@ -60,6 +65,8 @@ test_lib_SOURCES = \
|
|||
$(testlib_srcdir)/meta/function-erasure-test.cpp \
|
||||
$(testlib_srcdir)/meta/generator-test.cpp \
|
||||
$(testlib_srcdir)/meta/config-flags-test.cpp \
|
||||
$(testlib_srcdir)/meta/duck-detector-test.cpp \
|
||||
$(testlib_srcdir)/meta/iterable-classification-test.cpp \
|
||||
$(testlib_srcdir)/query/queryutilstest.cpp \
|
||||
$(testlib_srcdir)/removefromsettest.cpp \
|
||||
$(testlib_srcdir)/sanitised-identifier-test.cpp \
|
||||
|
|
|
|||
Loading…
Reference in a new issue