diff --git a/src/lib/mutex.c b/src/lib/mutex.c new file mode 100644 index 000000000..be36f58d2 --- /dev/null +++ b/src/lib/mutex.c @@ -0,0 +1,44 @@ +/* + mutex.c - mutex + + Copyright (C) CinelerraCV + 2007, Christian Thaeter + + 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/mutex.h" + +CinelerraMutex +cinelerra_mutex_init (CinelerraMutex self) +{ + if (self) + { + pthread_mutex_init (&self->mutex, NULL); + } + return self; +} + +CinelerraMutex +cinelerra_mutex_destroy (CinelerraMutex self) +{ + if (self) + { + if (pthread_mutex_destroy (&self->mutex)) + CINELERRA_DIE; + } + return self; +} + diff --git a/src/lib/mutex.h b/src/lib/mutex.h new file mode 100644 index 000000000..d14f82c78 --- /dev/null +++ b/src/lib/mutex.h @@ -0,0 +1,136 @@ +/* + mutex.h - mutal exclusion locking + + Copyright (C) CinelerraCV + 2007, Christian Thaeter + + 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 CINELERRA_MUTEX_H +#define CINELERRA_MUTEX_H + +#include "lib/locking.h" + +/** + * Mutex. + * + */ +struct cinelerra_mutex_struct +{ + pthread_mutex_t mutex; +}; +typedef struct cinelerra_mutex_struct cinelerra_mutex; +typedef cinelerra_mutex* CinelerraMutex; + + +/** + * Initialize a mutex variable + * @param self is a pointer to the mutex to be initialized + * @return self as given + */ +CinelerraMutex +cinelerra_mutex_init (CinelerraMutex self); + + +/** + * Destroy a mutex variable + * @param self is a pointer to the mutex to be destroyed + * @return self as given + */ +CinelerraMutex +cinelerra_mutex_destroy (CinelerraMutex self); + + + +/** + * mutexlock used to manage the state of a mutex variable. + */ +struct cinelerra_mutexlock_struct +{ + CinelerraMutex mutex; + enum cinelerra_lockstate state; +}; +typedef struct cinelerra_mutexlock_struct cinelerra_mutexlock; +typedef struct cinelerra_mutexlock_struct* CinelerraMutexlock; + +/* helper function for nobug */ +static inline void +cinelerra_mutexlock_ensureunlocked (CinelerraMutexlock self) +{ + ENSURE (self->state == CINELERRA_UNLOCKED, "forgot to unlock mutex"); +} + +/* override with a macro to use the cleanup checker */ +#define cinelerra_mutexlock \ +cinelerra_mutexlock NOBUG_CLEANUP(cinelerra_mutexlock_ensureunlocked) + + +/** + * initialize a mutexlock state + * @param self mutexlock to be initialized, must be an automatic variable + * @param mutex associated mutex + * @param state initial state of the mutex, either CINELERRA_LOCKED or CINELERRA_UNLOCKED + * @return self as given + * errors are fatal + */ +static inline CinelerraMutexlock +cinelerra_mutexlock_init (CinelerraMutexlock self, CinelerraMutex mutex, enum cinelerra_lockstate state) +{ + REQUIRE (self); + REQUIRE (mutex); + self->mutex = mutex; + self->state = state; + if (state == CINELERRA_LOCKED) + if (pthread_mutex_lock (&mutex->mutex)) + CINELERRA_DIE; + + return self; +} + +/** + * lock the mutex. + * must not already be locked + * @param self mutexlock associated with a mutex variable + */ +static inline void +cinelerra_mutexlock_lock (CinelerraMutexlock self) +{ + REQUIRE (self); + REQUIRE (self->state == CINELERRA_UNLOCKED, "mutex already locked"); + + if (pthread_mutex_lock (&self->mutex->mutex)) + CINELERRA_DIE; + + self->state = CINELERRA_LOCKED; +} + + +/** + * release mutex. + * a mutexlock must be unlocked before leaving scope + * @param self mutexlock associated with a mutex variable + */ +static inline int +cinelerra_mutexlock_unlock (CinelerraMutexlock self) +{ + REQUIRE (self); + REQUIRE (self->state == CINELERRA_LOCKED, "mutex was not locked"); + if (pthread_mutex_unlock (&self->mutex->mutex)) + CINELERRA_DIE; + self->state = CINELERRA_UNLOCKED; +} + +#endif diff --git a/tests/15locking.tests b/tests/15locking.tests index 1ef4938c5..7bea487d5 100644 --- a/tests/15locking.tests +++ b/tests/15locking.tests @@ -6,3 +6,11 @@ return: 134 END + + + +TEST "mutex not unlocked asserts" mutexforgotunlock < + + 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/condition.h" + +#if 0 +waiting_thread() +{ + lock; + wait; + unlock; +} + + +signaling_thread() +{ + signal(); +} +#endif + + +int +conditionforgotunlock () +{ + cinelerra_condition c; + cinelerra_condition_init (&c); + + cinelerra_conditionlock l; + cinelerra_conditionlock_init (&l, &c, CINELERRA_LOCKED); + return 0; +} diff --git a/tests/locking/mutex.c b/tests/locking/mutex.c new file mode 100644 index 000000000..3a1ff964f --- /dev/null +++ b/tests/locking/mutex.c @@ -0,0 +1,32 @@ +/* + test mutex functions + + Copyright (C) CinelerraCV + 2007, Christian Thaeter + + 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/mutex.h" + +int mutexforgotunlock() +{ + cinelerra_mutex m; + cinelerra_mutex_init (&m); + + cinelerra_mutexlock l; + cinelerra_mutexlock_init (&l, &m, CINELERRA_LOCKED); + return 0; +} diff --git a/tests/locking/test-locking.c b/tests/locking/test-locking.c new file mode 100644 index 000000000..78bc99779 --- /dev/null +++ b/tests/locking/test-locking.c @@ -0,0 +1,53 @@ +/* + test-locking.c - test locking functions + + Copyright (C) CinelerraCV + 2007, Christian Thaeter + + 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 +#include + +#include "lib/error.h" + +CINELERRA_ERROR_DEFINE(TEST, "test error"); + +int conditionforgotunlock (); +int mutexforgotunlock (); + + +int +main (int argc, char** argv) +{ + NOBUG_INIT; + + if (argc == 1) + return 0; + + if (!strcmp(argv[1], "conditionforgotunlock")) + { + return conditionforgotunlock (); + } + if (!strcmp(argv[1], "mutexforgotunlock")) + { + return mutexforgotunlock (); + } + else + return 1; + + return 0; +}