]> git.sur5r.net Git - openldap/commitdiff
ITS#8638 Add a recursive mutex to libldap_r for libevent
authorOndřej Kuzník <ondra@mistotebe.net>
Wed, 8 Mar 2017 17:03:18 +0000 (17:03 +0000)
committerOndřej Kuzník <ondra@mistotebe.net>
Tue, 26 Sep 2017 15:26:33 +0000 (16:26 +0100)
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
include/ldap_pvt_thread.h
libraries/libldap_r/thr_cthreads.c
libraries/libldap_r/thr_nt.c
libraries/libldap_r/thr_posix.c
libraries/libldap_r/thr_pth.c
libraries/libldap_r/thr_stub.c
libraries/libldap_r/thr_thr.c

index b0ead85f3e5456c1392b8c53c63f0e0ae0724ce7..555503b6fe0bd37e5f44975e66871978d10097fa 100644 (file)
@@ -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
 
 
index 6bef1028982bdfeab8906f1dc7e3adc6bb832db0..239e90cfc9cf66ea9c8cd3dd66a9fc4d199642e8 100644 (file)
@@ -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 ));
 
index de72276290456babddd251cd2b6e071f4a759d8b..59f2eca6d7df73011421e173e1f6a79ea6aa5a5a 100644 (file)
@@ -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 )
 {
index e5442f24d105592012ce1d88b81e65718486a2e2..56528a2058c060784621a0eb4b9adee211766c55 100644 (file)
@@ -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 )
 {
index 8c3d98552555200c05e472a7b8da092410af29d3..e68ec0549ce89b9b9d03a9eee14ed1f25404737f 100644 (file)
@@ -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();
index 93a98658147aea42667d7ff54b13d9fb55005571..6474905b604c5d8fcfc70c1094688aa9000540c2 100644 (file)
@@ -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 )
 {
index 48aa2387495aea0d8e4f50b6145dca8275e071f3..1aa4e5e11a0f09ba8aaf5f5f7c0b2e51b15a2da7 100644 (file)
@@ -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.
index 49102d3f711945aa1813d8d39011f9603ae8b523..34e45fefd0b7d0660beb372c7b5b6e41654a2afc 100644 (file)
@@ -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 )
 {