Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -447,14 +447,27 @@ ACX_PTHREAD([ CPPLAGS="$CPPFLAGS $PTHREAD_CFLAGS" LIBS="$LIBS $PTHREAD_LIBS" AC_DEFINE(OF_HAVE_PTHREADS, 1, [Whether we have pthreads]) + + AC_TRY_COMPILE([ + #include + ], [ + pthread_mutexattr_t attr; + pthread_mutexattr_settype(&attr, + PTHREAD_MUTEX_RECURSIVE); + ], [ + AC_DEFINE(OF_HAVE_RECURSIVE_PTHREAD_MUTEXES, 1, + [If pthread mutexes can be recursive]) + ]) + AC_CHECK_FUNC(pthread_spin_lock, [ AC_DEFINE(OF_HAVE_PTHREAD_SPINLOCKS, 1, [Whether we have pthread spinlocks]) ]) + AC_CHECK_FUNC(sched_yield, [ AC_DEFINE(OF_HAVE_SCHED_YIELD, 1, [Whether we have sched_yield]) ]) ], [ Index: src/objfw-defs.h.in ================================================================== --- src/objfw-defs.h.in +++ src/objfw-defs.h.in @@ -11,11 +11,12 @@ #undef OF_HAVE_OSATOMIC #undef OF_HAVE_OSATOMIC_64 #undef OF_HAVE_PROPERTIES #undef OF_HAVE_PTHREADS #undef OF_HAVE_PTHREAD_SPINLOCKS +#undef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES #undef OF_HAVE_SCHED_YIELD #undef OF_HAVE_SYS_SELECT_H #undef OF_OBJFW_RUNTIME #undef OF_PLUGINS #undef OF_THREADS #undef SIZE_MAX Index: src/threading.h ================================================================== --- src/threading.h +++ src/threading.h @@ -47,14 +47,18 @@ typedef pthread_spinlock_t of_spinlock_t; #else typedef of_mutex_t of_spinlock_t; #endif +#ifdef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES +# define of_rmutex_t of_mutex_t +#else typedef struct { of_mutex_t mutex; of_tlskey_t count; } of_rmutex_t; +#endif #if defined(OF_HAVE_PTHREADS) # define of_thread_is_current(t) pthread_equal(t, pthread_self()) # define of_thread_current pthread_self #elif defined(_WIN32) @@ -367,10 +371,35 @@ #else return of_mutex_free(spinlock); #endif } +#ifdef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES +static OF_INLINE BOOL +of_rmutex_new(of_mutex_t *mutex) +{ + pthread_mutexattr_t attr; + + if (pthread_mutexattr_init(&attr)) + return NO; + + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) + return NO; + + if (pthread_mutex_init(mutex, &attr)) + return NO; + + if (pthread_mutexattr_destroy(&attr)) + return NO; + + return YES; +} + +# define of_rmutex_lock of_mutex_lock +# define of_rmutex_unlock of_mutex_unlock +# define of_rmutex_free of_mutex_free +#else static OF_INLINE BOOL of_rmutex_new(of_rmutex_t *rmutex) { if (!of_mutex_new(&rmutex->mutex)) return NO; @@ -432,5 +461,6 @@ if (!of_tlskey_free(rmutex->count)) return NO; return YES; } +#endif