From a8f01cc88589a407cb9835b47ece8661c91e6a6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= Date: Wed, 8 Mar 2017 17:03:18 +0000 Subject: [PATCH] ITS#8638 Add a recursive mutex to libldap_r for libevent Most thread implementations suppport a native recursive mutex, use that where possible (especially when a regular mutex is recursive already). Also provide a macro for applications to test whether they can use the lock functions interchangeably. --- include/ldap_int_thread.h | 16 ++++++++++++++-- include/ldap_pvt_thread.h | 16 ++++++++++++++++ libraries/libldap_r/thr_cthreads.c | 28 ++++++++++++++++++++++++++++ libraries/libldap_r/thr_nt.c | 11 +++++++++++ libraries/libldap_r/thr_posix.c | 22 ++++++++++++++++++++++ libraries/libldap_r/thr_pth.c | 18 ++++++++++++++++++ libraries/libldap_r/thr_stub.c | 17 +++++++++++++++++ libraries/libldap_r/thr_thr.c | 15 +++++++++++++++ 8 files changed, 141 insertions(+), 2 deletions(-) diff --git a/include/ldap_int_thread.h b/include/ldap_int_thread.h index b0ead85f3e..555503b6fe 100644 --- a/include/ldap_int_thread.h +++ b/include/ldap_int_thread.h @@ -23,6 +23,9 @@ LDAP_F(int) ldap_int_thread_destroy LDAP_P(( void )); LDAP_END_DECL +LDAP_BEGIN_DECL +typedef struct ldap_int_thread_rmutex_s * ldap_int_thread_rmutex_t; +LDAP_END_DECL #ifndef _LDAP_INT_THREAD_H #define _LDAP_INT_THREAD_H @@ -41,7 +44,9 @@ LDAP_END_DECL LDAP_BEGIN_DECL +#define LDAP_THREAD_HAVE_NATIVE_RECURSIVE_MUTEX typedef pthread_t ldap_int_thread_t; +typedef pthread_mutex_t ldap_int_thread_mutex_recursive_t; typedef pthread_mutex_t ldap_int_thread_mutex_t; typedef pthread_cond_t ldap_int_thread_cond_t; typedef pthread_key_t ldap_int_thread_key_t; @@ -92,6 +97,7 @@ LDAP_END_DECL LDAP_BEGIN_DECL typedef cthread_t ldap_int_thread_t; +typedef ldap_int_thread_rmutex_t ldap_int_thread_mutex_recursive_t; typedef struct mutex ldap_int_thread_mutex_t; typedef struct condition ldap_int_thread_cond_t; typedef cthread_key_t ldap_int_thread_key_t; @@ -115,7 +121,9 @@ LDAP_END_DECL LDAP_BEGIN_DECL +#define LDAP_THREAD_HAVE_NATIVE_RECURSIVE_MUTEX typedef pth_t ldap_int_thread_t; +typedef pth_mutex_t ldap_int_thread_mutex_recursive_t; typedef pth_mutex_t ldap_int_thread_mutex_t; typedef pth_cond_t ldap_int_thread_cond_t; typedef pth_key_t ldap_int_thread_key_t; @@ -144,7 +152,9 @@ LDAP_END_DECL LDAP_BEGIN_DECL +#define LDAP_THREAD_HAVE_NATIVE_RECURSIVE_MUTEX typedef thread_t ldap_int_thread_t; +typedef mutex_t ldap_int_thread_mutex_recursive_t; typedef mutex_t ldap_int_thread_mutex_t; typedef cond_t ldap_int_thread_cond_t; typedef thread_key_t ldap_int_thread_key_t; @@ -175,7 +185,9 @@ typedef thread_key_t ldap_int_thread_key_t; LDAP_BEGIN_DECL +#define LDAP_THREAD_HAVE_NATIVE_RECURSIVE_MUTEX typedef unsigned long ldap_int_thread_t; +typedef HANDLE ldap_int_thread_mutex_recursive_t; typedef HANDLE ldap_int_thread_mutex_t; typedef HANDLE ldap_int_thread_cond_t; typedef DWORD ldap_int_thread_key_t; @@ -202,7 +214,9 @@ LDAP_END_DECL LDAP_BEGIN_DECL +#define LDAP_THREAD_HAVE_NATIVE_RECURSIVE_MUTEX typedef int ldap_int_thread_t; +typedef int ldap_int_thread_mutex_recursive_t; typedef int ldap_int_thread_mutex_t; typedef int ldap_int_thread_cond_t; typedef int ldap_int_thread_key_t; @@ -236,8 +250,6 @@ LDAP_F(int) ldap_int_thread_pool_shutdown ( void ); #ifndef LDAP_THREAD_HAVE_TPOOL typedef struct ldap_int_thread_pool_s * ldap_int_thread_pool_t; #endif - -typedef struct ldap_int_thread_rmutex_s * ldap_int_thread_rmutex_t; LDAP_END_DECL diff --git a/include/ldap_pvt_thread.h b/include/ldap_pvt_thread.h index 6bef102898..239e90cfc9 100644 --- a/include/ldap_pvt_thread.h +++ b/include/ldap_pvt_thread.h @@ -37,6 +37,7 @@ typedef ldap_int_thread_rdwr_t ldap_pvt_thread_rdwr_t; #define LDAP_PVT_MUTEX_FIRSTCREATE LDAP_INT_MUTEX_FIRSTCREATE #define LDAP_PVT_MUTEX_NULL LDAP_INT_MUTEX_NULL #endif +typedef ldap_int_thread_mutex_recursive_t ldap_pvt_thread_mutex_recursive_t; typedef ldap_int_thread_rmutex_t ldap_pvt_thread_rmutex_t; typedef ldap_int_thread_key_t ldap_pvt_thread_key_t; #endif /* !LDAP_PVT_THREAD_H_DONE */ @@ -111,9 +112,15 @@ ldap_pvt_thread_cond_wait LDAP_P(( LDAP_F( int ) ldap_pvt_thread_mutex_init LDAP_P(( ldap_pvt_thread_mutex_t *mutex )); +LDAP_F( int ) +ldap_pvt_thread_mutex_recursive_init LDAP_P(( ldap_pvt_thread_mutex_t *mutex )); + LDAP_F( int ) ldap_pvt_thread_mutex_destroy LDAP_P(( ldap_pvt_thread_mutex_t *mutex )); +LDAP_F( int ) +ldap_pvt_thread_mutex_recursive_destroy LDAP_P(( ldap_pvt_thread_mutex_recursive_t *mutex )); + LDAP_F( int ) ldap_pvt_thread_mutex_lock LDAP_P(( ldap_pvt_thread_mutex_t *mutex )); @@ -123,6 +130,15 @@ ldap_pvt_thread_mutex_trylock LDAP_P(( ldap_pvt_thread_mutex_t *mutex )); LDAP_F( int ) ldap_pvt_thread_mutex_unlock LDAP_P(( ldap_pvt_thread_mutex_t *mutex )); +LDAP_F( int ) +ldap_pvt_thread_mutex_recursive_lock LDAP_P(( ldap_pvt_thread_mutex_recursive_t *mutex )); + +LDAP_F( int ) +ldap_pvt_thread_mutex_recursive_trylock LDAP_P(( ldap_pvt_thread_mutex_recursive_t *mutex )); + +LDAP_F( int ) +ldap_pvt_thread_mutex_recursive_unlock LDAP_P(( ldap_pvt_thread_mutex_recursive_t *mutex )); + LDAP_F( int ) ldap_pvt_thread_rmutex_init LDAP_P(( ldap_pvt_thread_rmutex_t *rmutex )); diff --git a/libraries/libldap_r/thr_cthreads.c b/libraries/libldap_r/thr_cthreads.c index de72276290..59f2eca6d7 100644 --- a/libraries/libldap_r/thr_cthreads.c +++ b/libraries/libldap_r/thr_cthreads.c @@ -147,6 +147,34 @@ ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex ) return mutex_try_lock( mutex ); } +int ldap_pvt_thread_mutex_recursive_init( ldap_pvt_thread_mutex_recursive_t *mutex ) +{ + return ldap_pvt_thread_rmutex_init( mutex ); +} + +int ldap_pvt_thread_mutex_recursive_destroy( ldap_pvt_thread_mutex_recursive_t *mutex ) +{ + return ldap_pvt_thread_rmutex_destroy( mutex ); +} + +int +ldap_pvt_thread_mutex_recursive_lock( ldap_pvt_thread_mutex_recursive_t *mutex ) +{ + return ldap_pvt_thread_rmutex_lock( mutex, ldap_pvt_thread_self() ); +} + +int +ldap_pvt_thread_mutex_recursive_unlock( ldap_pvt_thread_mutex_recursive_t *mutex ) +{ + return ldap_pvt_thread_rmutex_unlock( mutex, ldap_pvt_thread_self() ); +} + +int +ldap_pvt_thread_mutex_recursive_trylock( ldap_pvt_thread_mutex_recursive_t *mp ) +{ + return ldap_pvt_thread_rmutex_trylock( mp, ldap_pvt_thread_self() ); +} + ldap_pvt_thread_t ldap_pvt_thread_self( void ) { diff --git a/libraries/libldap_r/thr_nt.c b/libraries/libldap_r/thr_nt.c index e5442f24d1..56528a2058 100644 --- a/libraries/libldap_r/thr_nt.c +++ b/libraries/libldap_r/thr_nt.c @@ -192,6 +192,17 @@ ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mp ) ? -1 : 0; } +int ldap_pvt_thread_mutex_recursive_init( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_init"))); +int ldap_pvt_thread_mutex_recursive_destroy( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_destroy"))); +int ldap_pvt_thread_mutex_recursive_lock( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_lock"))); +int ldap_pvt_thread_mutex_recursive_trylock( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_trylock"))); +int ldap_pvt_thread_mutex_recursive_unlock( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_unlock"))); + ldap_pvt_thread_t ldap_pvt_thread_self( void ) { diff --git a/libraries/libldap_r/thr_posix.c b/libraries/libldap_r/thr_posix.c index 8c3d985525..e68ec0549c 100644 --- a/libraries/libldap_r/thr_posix.c +++ b/libraries/libldap_r/thr_posix.c @@ -58,6 +58,8 @@ static pthread_mutexattr_t mutex_attr; # define LDAP_INT_THREAD_MUTEXATTR_DEFAULT &mutex_attr #endif +static pthread_mutexattr_t mutex_attr_recursive; + #if HAVE_PTHREADS < 7 #define ERRVAL(val) ((val) < 0 ? errno : 0) #else @@ -71,6 +73,10 @@ ldap_int_thread_initialize( void ) pthread_mutexattr_init( &mutex_attr ); pthread_mutexattr_settype( &mutex_attr, LDAP_INT_THREAD_MUTEXATTR ); #endif + if (pthread_mutexattr_init(&mutex_attr_recursive)) + return -1; + if (pthread_mutexattr_settype(&mutex_attr_recursive, PTHREAD_MUTEX_RECURSIVE)) + return -1; return 0; } @@ -84,6 +90,7 @@ ldap_int_thread_destroy( void ) #ifdef LDAP_INT_THREAD_MUTEXATTR pthread_mutexattr_destroy( &mutex_attr ); #endif + pthread_mutexattr_destroy( &mutex_attr_recursive ); return 0; } @@ -312,6 +319,21 @@ ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex ) return ERRVAL( pthread_mutex_unlock( mutex ) ); } +int +ldap_pvt_thread_mutex_recursive_init( ldap_pvt_thread_mutex_t *mutex ) +{ + return ERRVAL( pthread_mutex_init( mutex, &mutex_attr_recursive ) ); +} + +int ldap_pvt_thread_mutex_recursive_destroy( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_destroy"))); +int ldap_pvt_thread_mutex_recursive_lock( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_lock"))); +int ldap_pvt_thread_mutex_recursive_trylock( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_trylock"))); +int ldap_pvt_thread_mutex_recursive_unlock( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_unlock"))); + ldap_pvt_thread_t ldap_pvt_thread_self( void ) { return pthread_self(); diff --git a/libraries/libldap_r/thr_pth.c b/libraries/libldap_r/thr_pth.c index 93a9865814..6474905b60 100644 --- a/libraries/libldap_r/thr_pth.c +++ b/libraries/libldap_r/thr_pth.c @@ -129,6 +129,13 @@ ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex ) return( pth_mutex_init( mutex ) ? 0 : errno ); } +int +ldap_pvt_thread_mutex_recursive_init( ldap_pvt_thread_mutex_t *mutex ) +{ + /* All pth mutexes are recursive */ + return ldap_pvt_thread_mutex_init( mutex ); +} + int ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex ) { @@ -153,6 +160,17 @@ ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex ) return( pth_mutex_acquire( mutex, 1, NULL ) ? 0 : errno ); } +int ldap_pvt_thread_mutex_recursive_init( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_init"))); +int ldap_pvt_thread_mutex_recursive_destroy( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_destroy"))); +int ldap_pvt_thread_mutex_recursive_lock( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_lock"))); +int ldap_pvt_thread_mutex_recursive_trylock( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_trylock"))); +int ldap_pvt_thread_mutex_recursive_unlock( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_unlock"))); + ldap_pvt_thread_t ldap_pvt_thread_self( void ) { diff --git a/libraries/libldap_r/thr_stub.c b/libraries/libldap_r/thr_stub.c index 48aa238749..1aa4e5e11a 100644 --- a/libraries/libldap_r/thr_stub.c +++ b/libraries/libldap_r/thr_stub.c @@ -120,6 +120,12 @@ ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex ) return 0; } +int +ldap_pvt_thread_mutex_recursive_init( ldap_pvt_thread_mutex_t *mutex ) +{ + return 0; +} + int ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex ) { @@ -144,6 +150,17 @@ ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex ) return 0; } +int ldap_pvt_thread_mutex_recursive_init( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_init"))); +int ldap_pvt_thread_mutex_recursive_destroy( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_destroy"))); +int ldap_pvt_thread_mutex_recursive_lock( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_lock"))); +int ldap_pvt_thread_mutex_recursive_trylock( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_trylock"))); +int ldap_pvt_thread_mutex_recursive_unlock( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_unlock"))); + /* * NO_THREADS requires a separate tpool implementation since * generic ldap_pvt_thread_pool_wrapper loops forever. diff --git a/libraries/libldap_r/thr_thr.c b/libraries/libldap_r/thr_thr.c index 49102d3f71..34e45fefd0 100644 --- a/libraries/libldap_r/thr_thr.c +++ b/libraries/libldap_r/thr_thr.c @@ -153,6 +153,21 @@ ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mp ) return( mutex_trylock( mp ) ); } +int +ldap_pvt_thread_mutex_recursive_init( ldap_pvt_thread_mutex_recursive_t *mutex ) +{ + return( mutex_init( mutex, USYNC_THREAD | LOCK_RECURSIVE, NULL ) ); +} + +int ldap_pvt_thread_mutex_recursive_destroy( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_destroy"))); +int ldap_pvt_thread_mutex_recursive_lock( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_lock"))); +int ldap_pvt_thread_mutex_recursive_trylock( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_trylock"))); +int ldap_pvt_thread_mutex_recursive_unlock( ldap_pvt_thread_mutex_recursive_t *mutex ) + LDAP_GCCATTR((alias("ldap_pvt_thread_mutex_unlock"))); + ldap_pvt_thread_t ldap_pvt_thread_self( void ) {