diff --git a/boden/wege/weg.cc b/boden/wege/weg.cc index 6c8e56b85..c59bde39f 100644 --- a/boden/wege/weg.cc +++ b/boden/wege/weg.cc @@ -47,7 +47,8 @@ #ifdef MULTI_THREAD #include "../../utils/simthread.h" -static pthread_mutex_t weg_calc_image_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +static pthread_mutex_t weg_calc_image_mutex; +static recursive_mutex_maker_t weg_cim_maker(weg_calc_image_mutex); #endif /** diff --git a/obj/crossing.cc b/obj/crossing.cc index 75e4317c4..7420aca9b 100644 --- a/obj/crossing.cc +++ b/obj/crossing.cc @@ -28,7 +28,8 @@ #ifdef MULTI_THREAD #include "../utils/simthread.h" -static pthread_mutex_t crossing_logic_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +static pthread_mutex_t crossing_logic_mutex; +static recursive_mutex_maker_t crossing_lm_maker(crossing_logic_mutex); #endif diff --git a/obj/tunnel.cc b/obj/tunnel.cc index 48cc30978..483b6ced1 100644 --- a/obj/tunnel.cc +++ b/obj/tunnel.cc @@ -26,7 +26,8 @@ #ifdef MULTI_THREAD #include "../utils/simthread.h" -static pthread_mutex_t tunnel_calc_image_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +static pthread_mutex_t tunnel_calc_image_mutex; +static recursive_mutex_maker_t tunnel_cim_maker(tunnel_calc_image_mutex); #endif diff --git a/obj/wayobj.cc b/obj/wayobj.cc index 7e7135e8a..f37d66076 100644 --- a/obj/wayobj.cc +++ b/obj/wayobj.cc @@ -43,7 +43,8 @@ #ifdef MULTI_THREAD #include "../utils/simthread.h" -static pthread_mutex_t wayobj_calc_image_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +static pthread_mutex_t wayobj_calc_image_mutex; +static recursive_mutex_maker_t wayobj_cim_maker(wayobj_calc_image_mutex); #endif // the descriptions ... diff --git a/simworld.cc b/simworld.cc index d556e5295..d6845c10b 100644 --- a/simworld.cc +++ b/simworld.cc @@ -5117,7 +5117,8 @@ DBG_MESSAGE("karte_t::load()","Savegame version is %d", file.get_version()); #ifdef MULTI_THREAD -static pthread_mutex_t height_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +static pthread_mutex_t height_mutex; +static recursive_mutex_maker_t height_mutex_maker(height_mutex); #endif diff --git a/utils/simthread.cc b/utils/simthread.cc index ab92cc9bc..59237b32f 100644 --- a/utils/simthread.cc +++ b/utils/simthread.cc @@ -1,9 +1,9 @@ #include "simthread.h" -#if defined(_USE_POSIX_BARRIERS) || !defined(MULTI_THREAD) -// use native pthread barriers -// (and do not try to compile this file for non-multithread builds) -#else +#ifdef MULTI_THREAD +// do not try to compile this file for non-multithreaded builds + +#ifndef _USE_POSIX_BARRIERS // implement barriers using other pthread primitives #include @@ -54,3 +54,24 @@ int simthread_barrier_wait(simthread_barrier_t *barrier) } #endif + +#ifndef _SIMTHREAD_R_MUTEX_I +// initialize a recursive mutex by calling pthread_mutex_init() +#include + + +recursive_mutex_maker_t::recursive_mutex_maker_t(pthread_mutex_t &mutex) { + pthread_mutexattr_t attr; + + if (pthread_mutexattr_init(&attr) != 0 || + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0 || + pthread_mutex_init(&mutex, &attr) != 0 || + pthread_mutexattr_destroy(&attr) != 0) { + // Can't call dbg->error(), because this constructor + // may run before simu_main() calls init_logging(). + throw std::runtime_error("Can't make a recursive mutex!"); + } +} +#endif + +#endif diff --git a/utils/simthread.h b/utils/simthread.h index b6316a447..47b470e63 100644 --- a/utils/simthread.h +++ b/utils/simthread.h @@ -22,11 +22,24 @@ #include -// Mac OS X defines this initializers without _NP. -#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP -#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER +#if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP +// Linux glibc +#define _SIMTHREAD_R_MUTEX_I PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP +#elif defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER +// Mac OS X +#define _SIMTHREAD_R_MUTEX_I PTHREAD_RECURSIVE_MUTEX_INITIALIZER #endif +struct recursive_mutex_maker_t { +#ifdef _SIMTHREAD_R_MUTEX_I + recursive_mutex_maker_t(pthread_mutex_t &mutex) { + mutex = _SIMTHREAD_R_MUTEX_I; + } +#else + recursive_mutex_maker_t(pthread_mutex_t &mutex); +#endif +}; + // use our implementation if no posix barriers are available #if defined(_POSIX_BARRIERS) && (_POSIX_BARRIERS > 0) #define _USE_POSIX_BARRIERS