]> git.sur5r.net Git - openldap/commitdiff
Add thread debugging wrapper thr_debug.c and ldap_thr_debug.h in libldap_r/,
authorHallvard Furuseth <hallvard@openldap.org>
Sat, 17 Sep 2005 23:28:08 +0000 (23:28 +0000)
committerHallvard Furuseth <hallvard@openldap.org>
Sat, 17 Sep 2005 23:28:08 +0000 (23:28 +0000)
enabled with LDAP_THREAD_DEBUG (cpp macro and environment variable):

Move any ldap_pvt_* definitions from ldap_int_thread.h to ldap_pvt_thread.h.
#define ldap_int_thread_equal/ldap_pvt_thread_equal instead of tpool.c:TID_EQ.
Define some ldap_debug_*_t types, and LDAP_UINTPTR_T, in ldap_int_thread.h.
ldap_int_thread.h/ldap_pvt_thread.h can now be included multiple times, giving
different results depending on whether libldap_r/ldap_thr_debug.h was included.
Add some cleanup and some preprocessor hacks.
#define LDAP_THREAD*_IMPLEMENTATION in libldap_r/*.c, used by ldap_thr_debug.h.
Add PTHREAD_MUTEX_ERRORCHECK/PTHREAD_MUTEX_ERRORCHECK_NP in thr_posix.c.

15 files changed:
include/ldap_int_thread.h
include/ldap_pvt_thread.h
libraries/libldap_r/Makefile.in
libraries/libldap_r/ldap_thr_debug.h [new file with mode: 0644]
libraries/libldap_r/rdwr.c
libraries/libldap_r/thr_cthreads.c
libraries/libldap_r/thr_debug.c [new file with mode: 0644]
libraries/libldap_r/thr_lwp.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
libraries/libldap_r/threads.c
libraries/libldap_r/tpool.c

index 385fef52f64dae40f1fce5d7c1a5874e73b9b48e..307d85c86ebfafaa42a2a33d099551b03736033a 100644 (file)
  * <http://www.OpenLDAP.org/license.html>.
  */
 
+
+LDAP_BEGIN_DECL
+
+/* Can be done twice in libldap_r.  See libldap_r/ldap_thr_debug.h. */
+LDAP_F(int) ldap_int_thread_initialize LDAP_P(( void ));
+LDAP_F(int) ldap_int_thread_destroy    LDAP_P(( void ));
+
+LDAP_END_DECL
+
+
 #ifndef _LDAP_INT_THREAD_H
 #define _LDAP_INT_THREAD_H
 
@@ -35,6 +45,8 @@ typedef pthread_t             ldap_int_thread_t;
 typedef pthread_mutex_t                ldap_int_thread_mutex_t;
 typedef pthread_cond_t         ldap_int_thread_cond_t;
 
+#define ldap_int_thread_equal(a, b)    pthread_equal((a), (b))
+
 #if defined( _POSIX_REENTRANT_FUNCTIONS ) || \
        defined( _POSIX_THREAD_SAFE_FUNCTIONS ) || \
        defined( _POSIX_THREADSAFE_FUNCTIONS )
@@ -53,7 +65,7 @@ typedef pthread_cond_t                ldap_int_thread_cond_t;
 
 #if 0 && defined( HAVE_PTHREAD_RWLOCK_DESTROY )
 #define LDAP_THREAD_HAVE_RDWR 1
-typedef pthread_rwlock_t ldap_pvt_thread_rdwr_t;
+typedef pthread_rwlock_t ldap_int_thread_rdwr_t;
 #endif
 
 LDAP_END_DECL
@@ -97,7 +109,7 @@ typedef pth_cond_t   ldap_int_thread_cond_t;
 
 #if 0
 #define LDAP_THREAD_HAVE_RDWR 1
-typedef pth_rwlock_t ldap_pvt_thread_rdwr_t;
+typedef pth_rwlock_t ldap_int_thread_rdwr_t;
 #endif
 
 LDAP_END_DECL
@@ -155,6 +167,11 @@ typedef struct ldap_int_thread_lwp_cv ldap_int_thread_cond_t;
 LDAP_END_DECL
 
 #elif defined(HAVE_NT_THREADS)
+/*************************************
+ *                                   *
+ * thread definitions for NT threads *
+ *                                   *
+ *************************************/
 
 #include <process.h>
 #include <windows.h>
@@ -168,7 +185,6 @@ typedef HANDLE      ldap_int_thread_cond_t;
 LDAP_END_DECL
 
 #else
-
 /***********************************
  *                                 *
  * thread definitions for no       *
@@ -193,10 +209,17 @@ LDAP_END_DECL
 
 #endif /* no threads support */
 
+
 LDAP_BEGIN_DECL
 
-LDAP_F(int) ldap_int_thread_initialize LDAP_P(( void ));
-LDAP_F(int) ldap_int_thread_destroy LDAP_P(( void ));
+#ifndef ldap_int_thread_equal
+#define ldap_int_thread_equal(a, b)    ((a) == (b))
+#endif
+
+#ifndef LDAP_THREAD_HAVE_RDWR
+typedef struct ldap_int_thread_rdwr_s * ldap_int_thread_rdwr_t;
+#endif
+
 LDAP_F(int) ldap_int_thread_pool_startup ( void );
 LDAP_F(int) ldap_int_thread_pool_shutdown ( void );
 
@@ -206,4 +229,46 @@ typedef struct ldap_int_thread_pool_s * ldap_int_thread_pool_t;
 
 LDAP_END_DECL
 
+
+#if defined(LDAP_THREAD_DEBUG) && !((LDAP_THREAD_DEBUG +0) & 2U)
+#define LDAP_THREAD_DEBUG_WRAP 1
+#endif
+
+#ifdef LDAP_THREAD_DEBUG_WRAP
+/**************************************
+ *                                    *
+ * definitions for type-wrapped debug *
+ *                                    *
+ **************************************/
+
+LDAP_BEGIN_DECL
+
+#ifndef LDAP_UINTPTR_T /* May be configured in CPPFLAGS */
+#define LDAP_UINTPTR_T unsigned long
+#endif
+
+typedef union {
+       unsigned char                   *ptr;
+       LDAP_UINTPTR_T                  num;
+} ldap_debug_usage_info_t;
+
+typedef struct {
+       ldap_int_thread_mutex_t wrapped;
+       ldap_debug_usage_info_t usage;
+} ldap_debug_thread_mutex_t;
+
+typedef struct {
+       ldap_int_thread_cond_t  wrapped;
+       ldap_debug_usage_info_t usage;
+} ldap_debug_thread_cond_t;
+
+typedef struct {
+       ldap_int_thread_rdwr_t  wrapped;
+       ldap_debug_usage_info_t usage;
+} ldap_debug_thread_rdwr_t;
+
+LDAP_END_DECL
+
+#endif /* LDAP_THREAD_DEBUG_WRAP */
+
 #endif /* _LDAP_INT_THREAD_H */
index 79c821dd659ddf48255392bf7272de4337d6338e..47bcf129bb5e8a6c9836ac2044f5627b55ba311f 100644 (file)
  */
 
 #ifndef _LDAP_PVT_THREAD_H
-#define _LDAP_PVT_THREAD_H
+#define _LDAP_PVT_THREAD_H /* libldap_r/ldap_thr_debug.h #undefines this */
 
 #include "ldap_cdefs.h"
 #include "ldap_int_thread.h"
 
 LDAP_BEGIN_DECL
 
-typedef ldap_int_thread_t ldap_pvt_thread_t;
-typedef ldap_int_thread_mutex_t ldap_pvt_thread_mutex_t;
-typedef ldap_int_thread_cond_t ldap_pvt_thread_cond_t;
+#ifndef LDAP_PVT_THREAD_H_DONE
+typedef ldap_int_thread_t                      ldap_pvt_thread_t;
+#ifdef LDAP_THREAD_DEBUG_WRAP
+typedef ldap_debug_thread_mutex_t      ldap_pvt_thread_mutex_t;
+typedef ldap_debug_thread_cond_t       ldap_pvt_thread_cond_t;
+typedef ldap_debug_thread_rdwr_t       ldap_pvt_thread_rdwr_t;
+#else
+typedef ldap_int_thread_mutex_t                ldap_pvt_thread_mutex_t;
+typedef ldap_int_thread_cond_t         ldap_pvt_thread_cond_t;
+typedef ldap_int_thread_rdwr_t         ldap_pvt_thread_rdwr_t;
+#endif
+#endif /* !LDAP_PVT_THREAD_H_DONE */
+
+#define ldap_pvt_thread_equal          ldap_int_thread_equal
 
 LDAP_F( int )
 ldap_pvt_thread_initialize LDAP_P(( void ));
@@ -44,6 +55,7 @@ ldap_pvt_thread_set_concurrency LDAP_P(( int ));
 #define LDAP_PVT_THREAD_CREATE_JOINABLE 0
 #define LDAP_PVT_THREAD_CREATE_DETACHED 1
 
+#ifndef LDAP_PVT_THREAD_H_DONE
 #define        LDAP_PVT_THREAD_SET_STACK_SIZE
 #ifndef LDAP_PVT_THREAD_STACK_SIZE
        /* LARGE stack. Will be twice as large on 64 bit machine. */
@@ -52,6 +64,7 @@ ldap_pvt_thread_set_concurrency LDAP_P(( int ));
 #elif LDAP_PVT_THREAD_STACK_SIZE == 0
 #undef LDAP_PVT_THREAD_SET_STACK_SIZE
 #endif
+#endif /* !LDAP_PVT_THREAD_H_DONE */
 
 LDAP_F( int )
 ldap_pvt_thread_create LDAP_P((
@@ -107,10 +120,6 @@ ldap_pvt_thread_mutex_unlock LDAP_P(( ldap_pvt_thread_mutex_t *mutex ));
 LDAP_F( ldap_pvt_thread_t )
 ldap_pvt_thread_self LDAP_P(( void ));
 
-#ifndef LDAP_THREAD_HAVE_RDWR
-typedef struct ldap_int_thread_rdwr_s * ldap_pvt_thread_rdwr_t;
-#endif
-
 LDAP_F( int )
 ldap_pvt_thread_rdwr_init LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 
@@ -149,10 +158,12 @@ ldap_pvt_thread_rdwr_active LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 #define LDAP_PVT_THREAD_EINVAL EINVAL
 #define LDAP_PVT_THREAD_EBUSY EINVAL
 
+#ifndef LDAP_PVT_THREAD_H_DONE
 typedef ldap_int_thread_pool_t ldap_pvt_thread_pool_t;
 
 typedef void * (ldap_pvt_thread_start_t) LDAP_P((void *ctx, void *arg));
 typedef void (ldap_pvt_thread_pool_keyfree_t) LDAP_P((void *key, void *data));
+#endif /* !LDAP_PVT_THREAD_H_DONE */
 
 LDAP_F( int )
 ldap_pvt_thread_pool_init LDAP_P((
@@ -213,4 +224,5 @@ ldap_pvt_thread_pool_context_reset LDAP_P(( void *key ));
 
 LDAP_END_DECL
 
+#define LDAP_PVT_THREAD_H_DONE
 #endif /* _LDAP_THREAD_H */
index 09554ea9adec80640f45557b509dae4b56b295af..bc658b84f3e2d89877918cd512928124c6dc63f1 100644 (file)
@@ -31,10 +31,10 @@ XXSRCS    = apitest.c test.c \
        turn.c groupings.c txn.c ppolicy.c
 SRCS   = threads.c rdwr.c tpool.c rq.c \
        thr_posix.c thr_cthreads.c thr_thr.c thr_lwp.c thr_nt.c \
-       thr_pth.c thr_stub.c
+       thr_pth.c thr_stub.c thr_debug.c
 OBJS   = threads.lo rdwr.lo tpool.lo  rq.lo \
        thr_posix.lo thr_cthreads.lo thr_thr.lo thr_lwp.lo thr_nt.lo \
-       thr_pth.lo thr_stub.lo \
+       thr_pth.lo thr_stub.lo thr_debug.lo \
        bind.lo open.lo result.lo error.lo compare.lo search.lo \
        controls.lo messages.lo references.lo extended.lo cyrus.lo \
        modify.lo add.lo modrdn.lo delete.lo abandon.lo \
diff --git a/libraries/libldap_r/ldap_thr_debug.h b/libraries/libldap_r/ldap_thr_debug.h
new file mode 100644 (file)
index 0000000..9c15bb1
--- /dev/null
@@ -0,0 +1,175 @@
+/* ldap_thr_debug.h - preprocessor magic for LDAP_THREAD_DEBUG */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2005 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#ifdef LDAP_THREAD_DEBUG
+
+/*
+ * libldap_r .c files should include this file after ldap_pvt_thread.h,
+ * with the appropriate LDAP_THREAD*_IMPLEMENTATION macro defined.
+ */
+
+#ifndef _LDAP_PVT_THREAD_H
+#error "ldap_pvt_thread.h" must be included before "ldap_thr_debug.h"
+#endif
+
+/*
+ * Support for thr_debug.c:
+ *
+ * thr_debug.c defines the ldap_pvt_*() as wrappers around
+ * ldap_int_*(), and ldap_debug_*() around ldap_int_*().
+ *
+ * Renames ldap_pvt_thread_* names to ldap_int_thread_*, and a few
+ * ldap_int_*() names to ldap_debug_*().  Includes "ldap_pvt_thread.h"
+ * to declare these renamed functions, and undefines the macros
+ * afterwards when included from thr_debug.c.  So,
+ *
+ * libldap_r/<not thr_debug.c> define ldap_int_* instead of ldap_pvt_*.
+ * In thread.c, ldap_pvt_thread_<initialize/destroy>() will call
+ * ldap_debug_*() instead of ldap_int_*().
+ * In tpool.c, ldap_int_thread_pool_shutdown() has thr_debug support
+ * which treats ldap_pvt_thread_pool_destroy() the same way.
+ */
+
+#ifndef LDAP_THREAD_IMPLEMENTATION             /* for first part of threads.c */
+#define        ldap_int_thread_initialize              ldap_debug_thread_initialize
+#define        ldap_int_thread_destroy                 ldap_debug_thread_destroy
+#else /* LDAP_THREAD_IMPLEMENTATION    -- for thr_*.c and end of threads.c */
+#undef ldap_int_thread_initialize
+#undef ldap_int_thread_destroy
+#ifdef LDAP_THREAD_DEBUG_WRAP                  /* see ldap_pvt_thread.h */
+#define        ldap_pvt_thread_mutex_t                 ldap_int_thread_mutex_t
+#define        ldap_pvt_thread_cond_t                  ldap_int_thread_cond_t
+#endif
+#define        ldap_pvt_thread_sleep                   ldap_int_thread_sleep
+#define        ldap_pvt_thread_get_concurrency ldap_int_thread_get_concurrency
+#define        ldap_pvt_thread_set_concurrency ldap_int_thread_set_concurrency
+#define        ldap_pvt_thread_create                  ldap_int_thread_create
+#define        ldap_pvt_thread_exit                    ldap_int_thread_exit
+#define        ldap_pvt_thread_join                    ldap_int_thread_join
+#define        ldap_pvt_thread_kill                    ldap_int_thread_kill
+#define        ldap_pvt_thread_yield                   ldap_int_thread_yield
+#define        ldap_pvt_thread_cond_init               ldap_int_thread_cond_init
+#define        ldap_pvt_thread_cond_destroy    ldap_int_thread_cond_destroy
+#define        ldap_pvt_thread_cond_signal             ldap_int_thread_cond_signal
+#define        ldap_pvt_thread_cond_broadcast  ldap_int_thread_cond_broadcast
+#define        ldap_pvt_thread_cond_wait               ldap_int_thread_cond_wait
+#define        ldap_pvt_thread_mutex_init              ldap_int_thread_mutex_init
+#define        ldap_pvt_thread_mutex_destroy   ldap_int_thread_mutex_destroy
+#define        ldap_pvt_thread_mutex_lock              ldap_int_thread_mutex_lock
+#define        ldap_pvt_thread_mutex_trylock   ldap_int_thread_mutex_trylock
+#define        ldap_pvt_thread_mutex_unlock    ldap_int_thread_mutex_unlock
+#define        ldap_pvt_thread_self                    ldap_int_thread_self
+#endif /* LDAP_THREAD_IMPLEMENTATION */
+
+#ifdef LDAP_THREAD_RDWR_IMPLEMENTATION /* rdwr.c, thr_debug.c */
+#ifdef LDAP_THREAD_DEBUG_WRAP                  /* see ldap_pvt_thread.h */
+#define        ldap_pvt_thread_rdwr_t                  ldap_int_thread_rdwr_t
+#endif
+#define        ldap_pvt_thread_rdwr_init               ldap_int_thread_rdwr_init
+#define        ldap_pvt_thread_rdwr_destroy    ldap_int_thread_rdwr_destroy
+#define        ldap_pvt_thread_rdwr_rlock              ldap_int_thread_rdwr_rlock
+#define        ldap_pvt_thread_rdwr_rtrylock   ldap_int_thread_rdwr_rtrylock
+#define        ldap_pvt_thread_rdwr_runlock    ldap_int_thread_rdwr_runlock
+#define        ldap_pvt_thread_rdwr_wlock              ldap_int_thread_rdwr_wlock
+#define        ldap_pvt_thread_rdwr_wtrylock   ldap_int_thread_rdwr_wtrylock
+#define        ldap_pvt_thread_rdwr_wunlock    ldap_int_thread_rdwr_wunlock
+#define        ldap_pvt_thread_rdwr_readers    ldap_int_thread_rdwr_readers
+#define        ldap_pvt_thread_rdwr_writers    ldap_int_thread_rdwr_writers
+#define        ldap_pvt_thread_rdwr_active             ldap_int_thread_rdwr_active
+#endif /* LDAP_THREAD_RDWR_IMPLEMENTATION */
+
+#ifdef LDAP_THREAD_POOL_IMPLEMENTATION /* tpool.c, thr_stub.c, thr_debug.c */
+#ifdef LDAP_THREAD_DEBUG_WRAP                  /* see ldap_pvt_thread.h */
+#define        ldap_pvt_thread_pool_t                  ldap_int_thread_pool_t
+#endif
+#define        ldap_pvt_thread_pool_init               ldap_int_thread_pool_init
+#define        ldap_pvt_thread_pool_submit             ldap_int_thread_pool_submit
+#define        ldap_pvt_thread_pool_maxthreads ldap_int_thread_pool_maxthreads
+#define        ldap_pvt_thread_pool_backload   ldap_int_thread_pool_backload
+#define        ldap_pvt_thread_pool_pause              ldap_int_thread_pool_pause
+#define        ldap_pvt_thread_pool_resume             ldap_int_thread_pool_resume
+#define        ldap_pvt_thread_pool_destroy    ldap_int_thread_pool_destroy
+#define        ldap_pvt_thread_pool_getkey             ldap_int_thread_pool_getkey
+#define        ldap_pvt_thread_pool_setkey             ldap_int_thread_pool_setkey
+#define        ldap_pvt_thread_pool_purgekey   ldap_int_thread_pool_purgekey
+#define        ldap_pvt_thread_pool_context    ldap_int_thread_pool_context
+#define        ldap_pvt_thread_pool_context_reset ldap_int_thread_pool_context_reset
+#endif /* LDAP_THREAD_POOL_IMPLEMENTATION */
+
+#undef _LDAP_PVT_THREAD_H
+#include "ldap_pvt_thread.h"
+
+#ifdef LDAP_THREAD_POOL_IMPLEMENTATION /* tpool.c */
+/*
+ * tpool.c:ldap_int_thread_pool_shutdown() needs this.  Could not
+ * use it for ldap_pvt_thread.h above because of its use of LDAP_P().
+ */
+#undef ldap_pvt_thread_pool_destroy
+#define        ldap_pvt_thread_pool_destroy(p,r) ldap_int_thread_pool_destroy(p,r)
+#endif
+
+#ifdef LDAP_THREAD_DEBUG_IMPLEMENTATION        /* thr_debug.c */
+#undef ldap_pvt_thread_mutex_t
+#undef ldap_pvt_thread_cond_t
+#undef ldap_pvt_thread_sleep
+#undef ldap_pvt_thread_get_concurrency
+#undef ldap_pvt_thread_set_concurrency
+#undef ldap_pvt_thread_create
+#undef ldap_pvt_thread_exit
+#undef ldap_pvt_thread_join
+#undef ldap_pvt_thread_kill
+#undef ldap_pvt_thread_yield
+#undef ldap_pvt_thread_cond_init
+#undef ldap_pvt_thread_cond_destroy
+#undef ldap_pvt_thread_cond_signal
+#undef ldap_pvt_thread_cond_broadcast
+#undef ldap_pvt_thread_cond_wait
+#undef ldap_pvt_thread_mutex_init
+#undef ldap_pvt_thread_mutex_destroy
+#undef ldap_pvt_thread_mutex_lock
+#undef ldap_pvt_thread_mutex_trylock
+#undef ldap_pvt_thread_mutex_unlock
+#undef ldap_pvt_thread_self
+/* LDAP_THREAD_RDWR_IMPLEMENTATION: */
+#undef ldap_pvt_thread_rdwr_t
+#undef ldap_pvt_thread_rdwr_init
+#undef ldap_pvt_thread_rdwr_destroy
+#undef ldap_pvt_thread_rdwr_rlock
+#undef ldap_pvt_thread_rdwr_rtrylock
+#undef ldap_pvt_thread_rdwr_runlock
+#undef ldap_pvt_thread_rdwr_wlock
+#undef ldap_pvt_thread_rdwr_wtrylock
+#undef ldap_pvt_thread_rdwr_wunlock
+#undef ldap_pvt_thread_rdwr_readers
+#undef ldap_pvt_thread_rdwr_writers
+#undef ldap_pvt_thread_rdwr_active
+/* LDAP_THREAD_POOL_IMPLEMENTATION: */
+#undef ldap_pvt_thread_pool_t
+#undef ldap_pvt_thread_pool_init
+#undef ldap_pvt_thread_pool_submit
+#undef ldap_pvt_thread_pool_maxthreads
+#undef ldap_pvt_thread_pool_backload
+#undef ldap_pvt_thread_pool_pause
+#undef ldap_pvt_thread_pool_resume
+#undef ldap_pvt_thread_pool_destroy
+#undef ldap_pvt_thread_pool_getkey
+#undef ldap_pvt_thread_pool_setkey
+#undef ldap_pvt_thread_pool_purgekey
+#undef ldap_pvt_thread_pool_context
+#undef ldap_pvt_thread_pool_context_reset
+#endif /* LDAP_THREAD_DEBUG_IMPLEMENTATION */
+
+#endif /* LDAP_THREAD_DEBUG */
index 5acf713e115c0f2aeb147581a717189c4ea7600c..bbae423bc638a2aa8a0da8fc9fb7b08055cb4b2e 100644 (file)
@@ -40,7 +40,9 @@
 #include <ac/time.h>
 
 #include "ldap-int.h"
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_RDWR_IMPLEMENTATION
+#include "ldap_thr_debug.h"  /* May rename the symbols defined below */
 
 /*
  * implementations that provide their own compatible 
@@ -439,6 +441,6 @@ int ldap_pvt_thread_rdwr_active(ldap_pvt_thread_rdwr_t *rwlock)
               ldap_pvt_thread_rdwr_writers(rwlock));
 }
 
-#endif /* LDAP_DEBUG */
+#endif /* LDAP_RDWR_DEBUG */
 
 #endif /* LDAP_THREAD_HAVE_RDWR */
index d81e0101b54d4320ada9655566be442cf7211606..83ba5aeb504f1b98ddbb49b1bc6d27d836767079 100644 (file)
@@ -20,7 +20,9 @@
 #include "portable.h"
 
 #if defined( HAVE_MACH_CTHREADS )
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#include "ldap_thr_debug.h"  /* May rename the symbols defined below */
 
 int
 ldap_int_thread_initialize( void )
diff --git a/libraries/libldap_r/thr_debug.c b/libraries/libldap_r/thr_debug.c
new file mode 100644 (file)
index 0000000..cc69b06
--- /dev/null
@@ -0,0 +1,1029 @@
+/* thr_debug.c - wrapper around the chosen thread wrapper, for debugging. */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2005 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+/*
+ * This package provides three types of thread operation debugging:
+ *
+ * - Print error messages and abort() when thread operations fail:
+ *   Operations on threads, mutexes, condition variables, rdwr locks.
+ *   Some thread pool operations are also checked, but not those for
+ *   which failure can happen in normal slapd operation.
+ *
+ * - Wrap those types except threads and pools in structs that
+ *   contain a state variable or a pointer to dummy allocated memory,
+ *   and check that on all operations.  The dummy memory variant lets
+ *   malloc debuggers see some incorrect use as memory leaks, access
+ *   to freed memory, etc.
+ *
+ * - Print a count of leaked thread resources after cleanup.
+ *
+ * Compile-time (./configure) setup:  Macros defined in CPPFLAGS.
+ *
+ *   LDAP_THREAD_DEBUG or LDAP_THREAD_DEBUG=2
+ *      Enables debugging, but value & 2 turns off type wrapping.
+ *
+ *   LDAP_UINTPTR_T=integer type to hold pointers, preferably unsigned.
+ *      Used by dummy memory option "scramble". Default = unsigned long.
+ *
+ *   In addition, you may need to set up an implementation-specific way
+ *      to enable whatever error checking your thread library provides.
+ *      Currently only implemented for Posix threads (pthreads), where
+ *      you may need to define LDAP_INT_THREAD_MUTEXATTR.  The default
+ *      is PTHREAD_MUTEX_ERRORCHECK, or PTHREAD_MUTEX_ERRORCHECK_NP for
+ *      Linux threads.  See pthread_mutexattr_settype(3).
+ *
+ * Run-time configuration:  Environment variable LDAP_THREAD_DEBUG.
+ *
+ *   The variable may contain a comma- or space-separated option list.
+ *   Options:
+ *      off      - Disable this package.
+ *   Error checking:
+ *      noabort  - Do not abort() on errors.
+ *      noerror  - Do not report errors.  Implies noabort.
+ *      nocount  - Do not report counts of unreleased resources.
+ *   State variable/dummy memory, unless type wrapping is disabled:
+ *      noalloc  - Default.  Use a state variable, not dummy memory.
+ *      dupinit  - Implies noalloc.  Check if resources that have
+ *                 not been destroyed are reinitialized.  Tools that
+ *                 report uninitialized memory access should disable
+ *                 such warnings about debug_already_initialized().
+ *      alloc    - Allocate dummy memory and store pointers as-is.
+ *                 Malloc debuggers might not notice unreleased
+ *                 resources in global variables as memory leaks.
+ *      scramble - Store bitwise complement of dummy memory pointer.
+ *                 That never escapes memory leak detectors -
+ *                 but detection while the program is running will
+ *                 report active resources as leaks.  Do not
+ *                 use this if a garbage collector is in use:-)
+ *      adjptr   - Point to end of dummy memory.
+ *                 Purify reports these as "potential leaks" (PLK).
+ *                 I have not checked other malloc debuggers.
+ *   Tracing:
+ *      tracethreads - Report create/join/exit/kill of threads.
+ */
+
+#include "portable.h"
+
+#if defined( LDAP_THREAD_DEBUG )
+
+#include <stdio.h>
+#include <ac/errno.h>
+#include <ac/stdlib.h>
+#include <ac/string.h>
+
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#define LDAP_THREAD_DEBUG_IMPLEMENTATION
+#define LDAP_THREAD_RDWR_IMPLEMENTATION
+#define LDAP_THREAD_POOL_IMPLEMENTATION
+#include "ldap_thr_debug.h"  /* Get the underlying implementation */
+
+
+/* Options from environment variable $LDAP_THREAD_DEBUG */
+enum { Count_no = 0, Count_yes, Count_reported, Count_reported_more };
+static int nodebug, noabort, noerror, count = Count_yes, options_done;
+#ifdef LDAP_THREAD_DEBUG_WRAP
+enum { Wrap_noalloc, Wrap_alloc, Wrap_scramble, Wrap_adjptr };
+static int dupinit, wraptype = Wrap_noalloc, wrap_offset, unwrap_offset;
+#endif
+static int tracethreads;
+
+static int threading_enabled;
+
+enum {
+       Idx_unexited_thread, Idx_unjoined_thread, Idx_locked_mutex,
+       Idx_mutex, Idx_cond, Idx_rdwr, Idx_tpool, Idx_max
+};
+static int resource_counts[Idx_max];
+static const char *const resource_names[] = {
+       "unexited threads", "unjoined threads", "locked mutexes",
+       "mutexes", "conds", "rdwrs", "thread pools"
+};
+static ldap_int_thread_mutex_t resource_mutexes[Idx_max];
+
+
+/*
+ * Making ldap_pvt_thread_t a wrapper around ldap_int_thread_t would
+ * slow down ldap_pvt_thread_self(), so keep a list of threads instead.
+ */
+typedef struct ldap_debug_thread_s {
+       ldap_pvt_thread_t                       wrapped;
+       ldap_debug_usage_info_t         usage;
+       int                                                     detached;
+       int                                                     freeme, idx;
+} ldap_debug_thread_t;
+
+static ldap_debug_thread_t             **thread_info;
+static unsigned int                            thread_info_size, thread_info_used;
+static ldap_int_thread_mutex_t thread_info_mutex;
+
+
+#define WARN(var, msg)   (warn (__FILE__, __LINE__, (msg), #var, (var)))
+#define ERROR(var,msg)   (error(__FILE__, __LINE__, (msg), #var, (var)))
+#define WARN_IF(rc, msg) {if (rc) warn (__FILE__, __LINE__, (msg), #rc, (rc));}
+#define ERROR_IF(rc,msg) {if (rc) error(__FILE__, __LINE__, (msg), #rc, (rc));}
+
+#if 0
+static void
+warn( const char *file, int line, const char *msg, const char *var, int val )
+{
+       fprintf( stderr, "%s:%d: %s warning: %s is %d\n",
+               file, line, msg, var, val );
+}
+#endif
+
+static void
+error( const char *file, int line, const char *msg, const char *var, int val )
+{
+       if( !noerror ) {
+               fprintf( stderr, "%s:%d: %s error: %s is %d\n",
+                       file, line, msg, var, val );
+               if( !noabort )
+                       abort();
+       }
+}
+
+static void
+count_resource_leaks( void )
+{
+       int i, j;
+       char errbuf[200], *delim = "Leaked";
+       if( count == Count_yes ) {
+               count = Count_reported;
+#if 0 /* Could break if there are still threads after atexit */
+               for( i = j = 0; i < Idx_max; i++ )
+                       j |= ldap_int_thread_mutex_destroy( &resource_mutexes[i] );
+               WARN_IF( j, "ldap_debug_thread_destroy:mutexes" );
+#endif
+               for( i = j = 0; i < Idx_max; i++ ) {
+                       if( resource_counts[i] ) {
+                               j += sprintf( errbuf + j, "%s %d %s",
+                                       delim, resource_counts[i], resource_names[i] );
+                               delim = ",";
+                       }
+               }
+               if( j )
+                       fprintf( stderr, "%s:%d: %s.\n", __FILE__, __LINE__, errbuf );
+       }
+}
+
+static void
+get_options( void )
+{
+       static const struct option_info_s {
+               const char      *name;
+               int             *var, val;
+       } option_info[] = {
+               { "off",        &nodebug,  1 },
+               { "noabort",    &noabort,  1 },
+               { "noerror",    &noerror,  1 },
+               { "nocount",    &count,    Count_no },
+#ifdef LDAP_THREAD_DEBUG_WRAP
+               { "noalloc",    &wraptype, Wrap_noalloc },
+               { "dupinit",    &dupinit,  1 },
+               { "alloc",      &wraptype, Wrap_alloc },
+               { "adjptr",     &wraptype, Wrap_adjptr },
+               { "scramble",   &wraptype, Wrap_scramble },
+#endif
+               { "tracethreads", &tracethreads, 1 },
+               { NULL, NULL, 0 }
+       };
+       const char *s = getenv( "LDAP_THREAD_DEBUG" );
+       if( s != NULL ) {
+               while( *(s += strspn( s, ", \t\r\n" )) != '\0' ) {
+                       size_t optlen = strcspn( s, ", \t\r\n" );
+                       const struct option_info_s *oi;
+                       for( oi = option_info; oi->name; oi++ ) {
+                               if( strncasecmp( oi->name, s, optlen ) == 0 ) {
+                                       if( oi->name && oi->name[optlen] == '\0' ) {
+                                               *oi->var = oi->val;
+                                       } else {
+                                               fprintf( stderr, "Unknown $%s option '%.*s'\n",
+                                                       "LDAP_THREAD_DEBUG", (int) optlen, s );
+                                       }
+                                       break;
+                               }
+                       }
+                       s += optlen;
+               }
+       }
+       if( nodebug ) {
+               noabort = noerror = 1;
+               tracethreads = dupinit = 0;
+               count = Count_no;
+       }
+#ifdef LDAP_THREAD_DEBUG_WRAP
+       if( nodebug || dupinit ) {
+               wraptype = Wrap_noalloc;
+       } else if( wraptype == Wrap_scramble ) {
+               const unsigned char *dummy = (const unsigned char *)&option_info;
+               if( sizeof(LDAP_UINTPTR_T) < sizeof(void *)
+                       || (unsigned char *)~~(LDAP_UINTPTR_T) dummy != dummy
+                       || (unsigned char *)~~(LDAP_UINTPTR_T) (unsigned char *)0 )
+               {
+                       fprintf( stderr, "Misconfigured for $%s %s.  Using %s.\n",
+                               "LDAP_THREAD_DEBUG", "scramble", "adjptr" );
+                       wraptype = Wrap_adjptr;
+               }
+       }
+       unwrap_offset = -(wrap_offset = (wraptype == Wrap_adjptr));
+#endif
+       options_done = 1;
+}
+
+
+static char *
+thread_name( char *buf, int bufsize, ldap_pvt_thread_t thread )
+{
+       int i;
+       --bufsize;
+       if( bufsize > 2*sizeof(thread) )
+               bufsize = 2*sizeof(thread);
+       for( i = 0; i < bufsize; i += 2 )
+               snprintf( buf+i, 3, "%02x", ((unsigned char *)&thread)[i/2] );
+       return buf;
+}
+
+static void
+exit_thread_message( const ldap_pvt_thread_t thread )
+{
+       if( tracethreads ) {
+               char buf[40];
+               fprintf( stderr, "== Exiting thread %s ==\n",
+                       thread_name( buf, sizeof(buf), thread ) );
+       }
+}
+
+
+#ifndef LDAP_THREAD_DEBUG_WRAP
+
+#define        WRAPPED(ptr)                    (ptr)
+#define alloc_usage(ptr, msg)  ((void) 0)
+#define check_usage(ptr, msg)  ((void) 0)
+#define free_usage(ptr, msg)   ((void) 0)
+
+#define with_threads_lock(statement)   { statement; }
+#define get_new_thread_info(msg)               NULL
+#define update_thread_info(ti, th, det)        {}
+#define remove_thread_info(ti, msg)            ((void)0)
+#define get_thread_info(thread, msg)   NULL
+#define exiting_thread(msg)    exit_thread_message(ldap_pvt_thread_self())
+
+#else /* LDAP_THREAD_DEBUG_WRAP */
+
+#define        WRAPPED(ptr)                    (&(ptr)->wrapped)
+
+#define INITED_VALUE           0x12345678UL
+#define INITED_BYTE_VALUE      0xd5
+
+static int
+debug_already_initialized( const LDAP_UINTPTR_T *num )
+{
+       /* Valid programs will access uninitialized memory if dupinit */
+       return dupinit && *num == INITED_VALUE;
+}
+
+static void
+alloc_usage( ldap_debug_usage_info_t *usage, const char *msg )
+{
+       if( !options_done )
+               get_options();
+       if( wraptype == Wrap_noalloc ) {
+               ERROR_IF( debug_already_initialized( &usage->num ), msg );
+               usage->num = INITED_VALUE;
+       } else {
+               unsigned char *dummy = malloc( 1 );
+               assert( dummy != NULL );
+               *dummy = INITED_BYTE_VALUE;
+               if( wraptype == Wrap_scramble ) {
+                       usage->num = ~(LDAP_UINTPTR_T) dummy;
+                       assert( (unsigned char *)~usage->num == dummy );
+               } else {
+                       usage->ptr = dummy + wrap_offset;
+               }
+       }
+}
+
+static void
+check_usage( ldap_debug_usage_info_t *usage, const char *msg )
+{
+       if( wraptype == Wrap_noalloc ) {
+               ERROR_IF( usage->num != INITED_VALUE, msg );
+       } else if( wraptype == Wrap_scramble ) {
+               ERROR_IF( !usage->num, msg );
+               ERROR_IF( *(unsigned char *)~usage->num != INITED_BYTE_VALUE, msg );
+       } else {
+               ERROR_IF( !usage->ptr, msg );
+               ERROR_IF( usage->ptr[unwrap_offset] != INITED_BYTE_VALUE, msg );
+       }
+}
+
+static void
+free_usage( ldap_debug_usage_info_t *usage, const char *msg )
+{
+       if( wraptype == Wrap_noalloc ) {
+               usage->num = ~(LDAP_UINTPTR_T)INITED_VALUE;
+       } else {
+               unsigned char *dummy = (wraptype == Wrap_scramble
+                                       ? (unsigned char *)~usage->num
+                                       : usage->ptr + unwrap_offset);
+               *(volatile unsigned char *)dummy = (unsigned char)-1;
+               free( dummy );
+       }
+}
+
+#define with_threads_lock(statement) { \
+       if( !nodebug ) { \
+               int rc_wtl_ = ldap_int_thread_mutex_lock( &thread_info_mutex ); \
+               assert( rc_wtl_ == 0 ); \
+       } \
+    statement; \
+       if( !nodebug ) { \
+               int rc_wtl_ = ldap_int_thread_mutex_unlock( &thread_info_mutex ); \
+               assert( rc_wtl_ == 0 ); \
+       } \
+}
+
+static ldap_debug_thread_t *
+get_new_thread_info( const char *msg )
+{
+       if( nodebug )
+               return NULL;
+       if( thread_info_used >= thread_info_size ) {
+               unsigned int more = thread_info_size + 1; /* debug value. increase. */
+               unsigned int new_size = thread_info_size + more;
+               ldap_debug_thread_t *t = calloc( more, sizeof(ldap_debug_thread_t) );
+               assert( t != NULL );
+               t->freeme = 1;
+               thread_info = realloc( thread_info, new_size * sizeof(*thread_info) );
+               assert( thread_info != NULL );
+               while( thread_info_size < new_size ) {
+                       t->idx = thread_info_size;
+                       thread_info[thread_info_size++] = t++;
+               }
+       }
+       alloc_usage( &thread_info[thread_info_used]->usage, msg );
+       return thread_info[thread_info_used++];
+}
+
+static void
+update_thread_info(
+       ldap_debug_thread_t *t,
+       const ldap_pvt_thread_t *thread,
+       int detached )
+{
+       if( !nodebug ) {
+               t->wrapped = *thread;
+               t->detached = detached;
+       }
+}
+
+static void
+remove_thread_info( ldap_debug_thread_t *t, const char *msg )
+{
+       if( !nodebug ) {
+               ldap_debug_thread_t *last;
+               int idx;
+               free_usage( &t->usage, msg );
+               idx = t->idx;
+               assert( thread_info[idx] == t );
+               last = thread_info[--thread_info_used];
+               assert( last->idx == thread_info_used );
+               (thread_info[idx]              = last)->idx = idx;
+               (thread_info[thread_info_used] = t   )->idx = thread_info_used;
+       }
+}
+
+ldap_debug_thread_t *
+get_thread_info( ldap_pvt_thread_t *thread, const char *msg )
+{
+       unsigned int i;
+       ldap_debug_thread_t *t;
+       if( nodebug )
+               return NULL;
+       for( i = 0; i < thread_info_used; i++ ) {
+               if( ldap_pvt_thread_equal( *thread, thread_info[i]->wrapped ) )
+                       break;
+       }
+       ERROR_IF( i == thread_info_used, msg );
+       t = thread_info[i];
+       check_usage( &t->usage, msg );
+       return t;
+}
+
+static void
+exiting_thread( const char *msg )
+{
+       if( !nodebug ) {
+               ldap_pvt_thread_t thread;
+               thread = ldap_pvt_thread_self();
+               exit_thread_message( thread );
+               with_threads_lock({
+                       ldap_debug_thread_t *t = get_thread_info( &thread, msg );
+                       if( t->detached )
+                               remove_thread_info( t, msg );
+               });
+       }
+}
+
+#endif /* LDAP_THREAD_DEBUG_WRAP */
+
+
+static void
+adjust_count( int which, int adjust )
+{
+       int rc;
+       switch( count ) {
+       case Count_no:
+               break;
+       case Count_yes:
+               rc = ldap_int_thread_mutex_lock( &resource_mutexes[which] );
+               assert( rc == 0 );
+               resource_counts[which] += adjust;
+               rc = ldap_int_thread_mutex_unlock( &resource_mutexes[which] );
+               assert( rc == 0 );
+       case Count_reported:
+               fputs( "...more ldap_debug_thread activity after exit...\n", stderr );
+               count = Count_reported_more;
+               /* FALL THROUGH */
+       case Count_reported_more:
+               /* Not used, but result might be inspected with debugger */
+               /* (Hopefully threading is disabled by now...) */
+               resource_counts[which] += adjust;
+               break;
+       }
+}
+
+
+/* Wrappers for LDAP_THREAD_IMPLEMENTATION: */
+
+/* Used instead of ldap_int_thread_initialize by ldap_pvt_thread_initialize */
+int
+ldap_debug_thread_initialize( void )
+{
+       int i, rc, rc2;
+       if( !options_done )
+               get_options();
+       ERROR_IF( threading_enabled, "ldap_debug_thread_initialize" );
+       threading_enabled = 1;
+       rc = ldap_int_thread_initialize();
+       if( rc ) {
+               ERROR( rc, "ldap_debug_thread_initialize:threads" );
+               threading_enabled = 0;
+       } else {
+               rc2 = ldap_int_thread_mutex_init( &thread_info_mutex );
+               assert( rc2 == 0 );
+               if( count != Count_no ) {
+                       for( i = rc2 = 0; i < Idx_max; i++ )
+                               rc2 |= ldap_int_thread_mutex_init( &resource_mutexes[i] );
+                       assert( rc2 == 0 );
+                       /* FIXME: Only for static libldap_r as in init.c? If so, why? */
+                       atexit( count_resource_leaks );
+               }
+       }
+       return rc;
+}
+
+/* Used instead of ldap_int_thread_destroy by ldap_pvt_thread_destroy */
+int
+ldap_debug_thread_destroy( void )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_debug_thread_destroy" );
+       /* sleep(1) -- need to wait for thread pool to finish? */
+       rc = ldap_int_thread_destroy();
+       if( rc ) {
+               ERROR( rc, "ldap_debug_thread_destroy:threads" );
+       } else {
+               threading_enabled = 0;
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_set_concurrency( int n )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_set_concurrency" );
+       rc = ldap_int_thread_set_concurrency( n );
+       ERROR_IF( rc, "ldap_pvt_thread_set_concurrency" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_get_concurrency( void )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_get_concurrency" );
+       rc = ldap_int_thread_get_concurrency();
+       ERROR_IF( rc, "ldap_pvt_thread_get_concurrency" );
+       return rc;
+}
+
+unsigned int
+ldap_pvt_thread_sleep( unsigned int interval )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_sleep" );
+       rc = ldap_int_thread_sleep( interval );
+       ERROR_IF( rc, "ldap_pvt_thread_sleep" );
+       return 0;
+}
+
+int
+ldap_pvt_thread_create(
+       ldap_pvt_thread_t *thread,
+       int detach,
+       void *(*start_routine)( void * ),
+       void *arg )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_create" );
+       if( !options_done )
+               get_options();
+       with_threads_lock({
+               ldap_debug_thread_t *t;
+               t = get_new_thread_info( "ldap_pvt_thread_create" );
+               rc = ldap_int_thread_create( thread, detach, start_routine, arg );
+               if( rc ) {
+                       ERROR( rc, "ldap_pvt_thread_create" );
+                       remove_thread_info( t, "ldap_pvt_thread_init" );
+               } else {
+                       update_thread_info( t, thread, detach );
+               }
+       });
+       if( rc == 0 ) {
+               if( tracethreads ) {
+                       char buf[40];
+                       fprintf( stderr, "== Created thread %s%s ==\n",
+                               thread_name( buf, sizeof(buf), *thread ),
+                               detach ? " (detached)" : "" );
+               }
+               adjust_count( Idx_unexited_thread, +1 );
+               if( !detach )
+                       adjust_count( Idx_unjoined_thread, +1 );
+       }
+       return rc;
+}
+
+void
+ldap_pvt_thread_exit( void *retval )
+{
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_exit" );
+       adjust_count( Idx_unexited_thread, -1 );
+       exiting_thread( "ldap_pvt_thread_exit" );
+       ldap_int_thread_exit( retval );
+}
+
+int
+ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
+{
+       int rc;
+       ldap_debug_thread_t *t;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_join" );
+       if( tracethreads ) {
+               char buf[40];
+               fprintf( stderr, "== Joining thread %s ==\n",
+                       thread_name( buf, sizeof(buf), thread ) );
+       }
+       with_threads_lock(
+               t = get_thread_info( &thread, "ldap_pvt_thread_join" ) );
+       rc = ldap_int_thread_join( thread, thread_return );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_join" );
+       } else {
+               with_threads_lock(
+                       remove_thread_info( t, "ldap_pvt_thread_join" ) );
+               adjust_count( Idx_unjoined_thread, -1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_kill( ldap_pvt_thread_t thread, int signo )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_kill" );
+       if( tracethreads ) {
+               char buf[40];
+               fprintf( stderr, "== Killing thread %s (sig %i) ==\n",
+                       thread_name( buf, sizeof(buf), thread ), signo );
+       }
+       rc = ldap_int_thread_kill( thread, signo );
+       ERROR_IF( rc, "ldap_pvt_thread_kill" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_yield( void )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_yield" );
+       rc = ldap_int_thread_yield();
+       ERROR_IF( rc, "ldap_pvt_thread_yield" );
+       return rc;
+}
+
+ldap_pvt_thread_t
+ldap_pvt_thread_self( void )
+{
+#if 0 /* Function is used by ch_free() via slap_sl_contxt() in slapd */
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_self" );
+#endif
+       return ldap_int_thread_self();
+}
+
+int
+ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
+{
+       int rc;
+       alloc_usage( &cond->usage, "ldap_pvt_thread_cond_init" );
+       rc = ldap_int_thread_cond_init( WRAPPED( cond ) );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_cond_init" );
+               free_usage( &cond->usage, "ldap_pvt_thread_cond_init" );
+       } else {
+               adjust_count( Idx_cond, +1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_cond_destroy( ldap_pvt_thread_cond_t *cond )
+{
+       int rc;
+       check_usage( &cond->usage, "ldap_pvt_thread_cond_destroy" );
+       rc = ldap_int_thread_cond_destroy( WRAPPED( cond ) );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_cond_destroy" );
+       } else {
+               free_usage( &cond->usage, "ldap_pvt_thread_cond_destroy" );
+               adjust_count( Idx_cond, -1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
+{
+       int rc;
+       check_usage( &cond->usage, "ldap_pvt_thread_cond_signal" );
+       rc = ldap_int_thread_cond_signal( WRAPPED( cond ) );
+       ERROR_IF( rc, "ldap_pvt_thread_cond_signal" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
+{
+       int rc;
+       check_usage( &cond->usage, "ldap_pvt_thread_cond_broadcast" );
+       rc = ldap_int_thread_cond_broadcast( WRAPPED( cond ) );
+       ERROR_IF( rc, "ldap_pvt_thread_cond_broadcast" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_cond_wait(
+       ldap_pvt_thread_cond_t *cond,
+       ldap_pvt_thread_mutex_t *mutex )
+{
+       int rc;
+       check_usage( &cond->usage, "ldap_pvt_thread_cond_wait:cond" );
+       check_usage( &mutex->usage, "ldap_pvt_thread_cond_wait:mutex" );
+       adjust_count( Idx_locked_mutex, -1 );
+       rc = ldap_int_thread_cond_wait( WRAPPED( cond ), WRAPPED( mutex ) );
+       adjust_count( Idx_locked_mutex, +1 );
+       ERROR_IF( rc, "ldap_pvt_thread_cond_wait" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
+{
+       int rc;
+       alloc_usage( &mutex->usage, "ldap_pvt_thread_mutex_init" );
+       rc = ldap_int_thread_mutex_init( WRAPPED( mutex ) );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_mutex_init" );
+               free_usage( &mutex->usage, "ldap_pvt_thread_mutex_init" );
+       } else {
+               adjust_count( Idx_mutex, +1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex )
+{
+       int rc;
+       check_usage( &mutex->usage, "ldap_pvt_thread_mutex_destroy" );
+       rc = ldap_int_thread_mutex_destroy( WRAPPED( mutex ) );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_mutex_destroy" );
+       } else {
+               free_usage( &mutex->usage, "ldap_pvt_thread_mutex_destroy" );
+               adjust_count( Idx_mutex, -1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
+{
+       int rc;
+       check_usage( &mutex->usage, "ldap_pvt_thread_mutex_lock" );
+       rc = ldap_int_thread_mutex_lock( WRAPPED( mutex ) );
+       if( rc ) {
+               ERROR_IF( rc, "ldap_pvt_thread_mutex_lock" );
+       } else {
+               adjust_count( Idx_locked_mutex, +1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_mutex_trylock( ldap_pvt_thread_mutex_t *mutex )
+{
+       int rc;
+       check_usage( &mutex->usage, "ldap_pvt_thread_mutex_trylock" );
+       rc = ldap_int_thread_mutex_trylock( WRAPPED( mutex ) );
+       if( rc == 0 )
+               adjust_count( Idx_locked_mutex, +1 );
+       return rc;
+}
+
+int
+ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
+{
+       int rc;
+       check_usage( &mutex->usage, "ldap_pvt_thread_mutex_unlock" );
+       rc = ldap_int_thread_mutex_unlock( WRAPPED( mutex ) );
+       if( rc ) {
+               ERROR_IF( rc, "ldap_pvt_thread_mutex_unlock" );
+       } else {
+               adjust_count( Idx_locked_mutex, -1 );
+       }
+       return rc;
+}
+
+
+/* Wrappers for LDAP_THREAD_RDWR_IMPLEMENTATION: */
+
+int
+ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       int rc;
+       alloc_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_init" );
+       rc = ldap_int_thread_rdwr_init( WRAPPED( rwlock ) );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_rdwr_init" );
+               free_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_init" );
+       } else {
+               adjust_count( Idx_rdwr, +1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_rdwr_destroy( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       int rc;
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_destroy" );
+       rc = ldap_int_thread_rdwr_destroy( WRAPPED( rwlock ) );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_rdwr_destroy" );
+       } else {
+               free_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_destroy" );
+               adjust_count( Idx_rdwr, -1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_rdwr_rlock( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       int rc;
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_rlock" );
+       rc = ldap_int_thread_rdwr_rlock( WRAPPED( rwlock ) );
+       ERROR_IF( rc, "ldap_pvt_thread_rdwr_rlock" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_rdwr_rtrylock( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_rtrylock" );
+       return ldap_int_thread_rdwr_rtrylock( WRAPPED( rwlock ) );
+}
+
+int
+ldap_pvt_thread_rdwr_runlock( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       int rc;
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_runlock" );
+       rc = ldap_int_thread_rdwr_runlock( WRAPPED( rwlock ) );
+       ERROR_IF( rc, "ldap_pvt_thread_rdwr_runlock" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       int rc;
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_wlock" );
+       rc = ldap_int_thread_rdwr_wlock( WRAPPED( rwlock ) );
+       ERROR_IF( rc, "ldap_pvt_thread_rdwr_wlock" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_wtrylock" );
+       return ldap_int_thread_rdwr_wtrylock( WRAPPED( rwlock ) );
+}
+
+int
+ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       int rc;
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_wunlock" );
+       rc = ldap_int_thread_rdwr_wunlock( WRAPPED( rwlock ) );
+       ERROR_IF( rc, "ldap_pvt_thread_rdwr_wunlock" );
+       return rc;
+}
+
+#ifdef LDAP_RDWR_DEBUG
+
+int
+ldap_pvt_thread_rdwr_readers( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_readers" );
+       return ldap_int_thread_rdwr_readers( WRAPPED( rwlock ) );
+}
+
+int
+ldap_pvt_thread_rdwr_writers( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_writers" );
+       return ldap_int_thread_rdwr_writers( WRAPPED( rwlock ) );
+}
+
+int
+ldap_pvt_thread_rdwr_active( ldap_pvt_thread_rdwr_t *rwlock )
+{
+       check_usage( &rwlock->usage, "ldap_pvt_thread_rdwr_active" );
+       return ldap_int_thread_rdwr_active( WRAPPED( rwlock ) );
+}
+
+#endif /* LDAP_RDWR_DEBUG */
+
+
+/* Some wrappers for LDAP_THREAD_POOL_IMPLEMENTATION: */
+#ifdef LDAP_THREAD_POOL_IMPLEMENTATION
+
+int
+ldap_pvt_thread_pool_init(
+       ldap_pvt_thread_pool_t *tpool,
+       int max_threads,
+       int max_pending )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_init" );
+       rc = ldap_int_thread_pool_init( tpool, max_threads, max_pending );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_pool_init" );
+       } else {
+               adjust_count( Idx_tpool, +1 );
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_pool_submit(
+       ldap_pvt_thread_pool_t *tpool,
+       ldap_pvt_thread_start_t *start_routine, void *arg )
+{
+       int rc, has_pool;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_submit" );
+       has_pool = (tpool != NULL && *tpool != NULL);
+       rc = ldap_int_thread_pool_submit( tpool, start_routine, arg );
+       if( has_pool )
+               ERROR_IF( rc, "ldap_pvt_thread_pool_submit" );
+       return rc;
+}
+
+int
+ldap_pvt_thread_pool_maxthreads(
+       ldap_pvt_thread_pool_t *tpool,
+       int max_threads )
+{
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_maxthreads" );
+       return ldap_int_thread_pool_maxthreads( tpool, max_threads );
+}
+
+int
+ldap_pvt_thread_pool_backload( ldap_pvt_thread_pool_t *tpool )
+{
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_backload" );
+       return ldap_int_thread_pool_backload( tpool );
+}
+
+int
+ldap_pvt_thread_pool_destroy( ldap_pvt_thread_pool_t *tpool, int run_pending )
+{
+       int rc, has_pool;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_destroy" );
+       has_pool = (tpool != NULL && *tpool != NULL);
+       rc = ldap_int_thread_pool_destroy( tpool, run_pending );
+       if( has_pool ) {
+               if( rc ) {
+                       ERROR( rc, "ldap_pvt_thread_pool_destroy" );
+               } else {
+                       adjust_count( Idx_tpool, -1 );
+               }
+       }
+       return rc;
+}
+
+int
+ldap_pvt_thread_pool_pause( ldap_pvt_thread_pool_t *tpool )
+{
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_pause" );
+       return ldap_int_thread_pool_pause( tpool );
+}
+
+int
+ldap_pvt_thread_pool_resume( ldap_pvt_thread_pool_t *tpool )
+{
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_resume" );
+       return ldap_int_thread_pool_resume( tpool );
+}
+
+int
+ldap_pvt_thread_pool_getkey(
+       void *xctx,
+       void *key,
+       void **data,
+       ldap_pvt_thread_pool_keyfree_t **kfree )
+{
+#if 0 /* Function is used by ch_free() via slap_sl_contxt() in slapd */
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_getkey" );
+#endif
+       return ldap_int_thread_pool_getkey( xctx, key, data, kfree );
+}
+
+int
+ldap_pvt_thread_pool_setkey(
+       void *xctx,
+       void *key,
+       void *data,
+       ldap_pvt_thread_pool_keyfree_t *kfree )
+{
+       int rc;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_setkey" );
+       rc = ldap_int_thread_pool_setkey( xctx, key, data, kfree );
+       ERROR_IF( rc, "ldap_pvt_thread_pool_setkey" );
+       return rc;
+}
+
+void
+ldap_pvt_thread_pool_purgekey( void *key )
+{
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_purgekey" );
+       ldap_int_thread_pool_purgekey( key );
+}
+
+void *
+ldap_pvt_thread_pool_context( void )
+{
+#if 0 /* Function is used by ch_free() via slap_sl_contxt() in slapd */
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_context" );
+#endif
+       return ldap_int_thread_pool_context();
+}
+
+void
+ldap_pvt_thread_pool_context_reset( void *vctx )
+{
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_context_reset" );
+       ldap_int_thread_pool_context_reset( vctx );
+}
+
+#endif /* LDAP_THREAD_POOL_IMPLEMENTATION */
+
+#endif /* LDAP_THREAD_DEBUG */
index 6d66e391365605157287bec7befd0fa8aa12ff72..be72e98976e3b68f952033baea9e9f416302401f 100644 (file)
@@ -38,7 +38,9 @@
 
 #include "ldap-int.h"
 
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#include "ldap_thr_debug.h"     /* May rename the symbols defined below */
 
 #include <lwp/lwp.h>
 #include <lwp/stackdep.h>
@@ -67,7 +69,7 @@ ldap_int_thread_initialize( void )
 int
 ldap_int_thread_destroy( void )
 {
-       /* need to destory lwp_scheduler thread and clean up private
+       /* need to destroy lwp_scheduler thread and clean up private
                variables */
        return 0;
 }
@@ -311,7 +313,7 @@ ldap_pvt_thread_cond_signal( ldap_pvt_thread_cond_t *cond )
 
 int 
 ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond, 
-       ldap_int_thread_mutex_t *mutex )
+       ldap_pvt_thread_mutex_t *mutex )
 {
        if ( ! cond->lcv_created ) {
                cv_create( &cond->lcv_cv, *mutex );
index 24a7a8d4ae431b5dd029ccbdf37fb450acdb058f..8953f4bdafc49f54a8fc8ae03b56ad558caf31b9 100644 (file)
@@ -18,7 +18,9 @@
 
 #if defined( HAVE_NT_THREADS )
 
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#include "ldap_thr_debug.h"     /* May rename the symbols defined below */
 
 typedef struct ldap_int_thread_s {
        long tid;
index 0d353206fafca11a6cd67ebbad8ba16288c1d20a..cb964d982d4db72329132b0c1a36d4297608a8de 100644 (file)
 
 #include <ac/errno.h>
 
-#include "ldap_pvt_thread.h"
-
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#define LDAP_THREAD_RDWR_IMPLEMENTATION
+#include "ldap_thr_debug.h"     /* May rename the symbols defined below */
 
 #if HAVE_PTHREADS < 6
 #  define LDAP_INT_THREAD_ATTR_DEFAULT         pthread_attr_default
 #else
 #  define LDAP_INT_THREAD_ATTR_DEFAULT         NULL
 #  define LDAP_INT_THREAD_CONDATTR_DEFAULT     NULL
-#  define LDAP_INT_THREAD_MUTEXATTR_DEFAULT    NULL
+#  define LDAP_INT_THREAD_MUTEXATTR_DEFAULT NULL
 #endif
 
+#ifdef LDAP_THREAD_DEBUG
+#  if defined LDAP_INT_THREAD_MUTEXATTR        /* May be defined in CPPFLAGS */
+#  elif defined HAVE_PTHREAD_KILL_OTHER_THREADS_NP
+        /* LinuxThreads hack */
+#    define LDAP_INT_THREAD_MUTEXATTR  PTHREAD_MUTEX_ERRORCHECK_NP
+#  else
+#    define LDAP_INT_THREAD_MUTEXATTR  PTHREAD_MUTEX_ERRORCHECK
+#  endif
+static pthread_mutexattr_t mutex_attr;
+#  undef  LDAP_INT_THREAD_MUTEXATTR_DEFAULT
+#  define LDAP_INT_THREAD_MUTEXATTR_DEFAULT &mutex_attr
+#endif
 
 int
 ldap_int_thread_initialize( void )
 {
+#ifdef LDAP_INT_THREAD_MUTEXATTR
+       pthread_mutexattr_init( &mutex_attr );
+       pthread_mutexattr_settype( &mutex_attr, LDAP_INT_THREAD_MUTEXATTR );
+#endif
        return 0;
 }
 
@@ -46,6 +64,9 @@ ldap_int_thread_destroy( void )
 #ifdef HAVE_PTHREAD_KILL_OTHER_THREADS_NP
        /* LinuxThreads: kill clones */
        pthread_kill_other_threads_np();
+#endif
+#ifdef LDAP_INT_THREAD_MUTEXATTR
+       pthread_mutexattr_destroy( &mutex_attr );
 #endif
        return 0;
 }
@@ -407,7 +428,7 @@ int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
 #endif
 }
 
-#endif /* HAVE_PTHREAD_RDLOCK_DESTROY */
+#endif /* HAVE_PTHREAD_RWLOCK_DESTROY */
 #endif /* LDAP_THREAD_HAVE_RDWR */
 #endif /* HAVE_PTHREADS */
 
index 9b413ebd1519353cb0ce914b99822517885d7b26..2d6012ba96361ba4b2340e29dcd6b30802894820 100644 (file)
 
 #if defined( HAVE_GNU_PTH )
 
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#define LDAP_THREAD_RDWR_IMPLEMENTATION
+#include "ldap_thr_debug.h"     /* May rename the symbols defined below */
+
 #include <errno.h>
 
 /*******************
index 03c3b1be60fbf5149ebcdf79b5f89c0f1c9ed27a..c4db69659ad149d20ef8afd497818d66f04dd56a 100644 (file)
 
 #if defined( NO_THREADS )
 
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#define LDAP_THREAD_POOL_IMPLEMENTATION
+#include "ldap_thr_debug.h"  /* May rename the symbols defined below */
 
 /***********************************************************************
  *                                                                     *
index e609365447c5c0f4f36cffc2bc868dcad893d967..edbd78a3499845d5c2f8cf606f72ef65b7e27b99 100644 (file)
@@ -18,7 +18,9 @@
 
 #if defined( HAVE_THR )
 
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#define LDAP_THREAD_IMPLEMENTATION
+#include "ldap_thr_debug.h"     /* May rename the symbols defined below */
 
 /*******************
  *                 *
index d19400b971abe62ab6bbc430b9640c0c0c884848..e2ae4e5211968c66c6b6a04bcd463c048c4f6e1f 100644 (file)
@@ -22,7 +22,8 @@
 #include <ac/string.h>
 #include <ac/unistd.h>
 
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
+#include "ldap_thr_debug.h"  /* May redirect thread initialize/destroy calls */
 
 
 /*
@@ -60,6 +61,15 @@ int ldap_pvt_thread_destroy( void )
        return ldap_int_thread_destroy();
 }
 
+
+/*
+ * Default implementations of some LDAP thread routines
+ */
+
+#define LDAP_THREAD_IMPLEMENTATION
+#include "ldap_thr_debug.h"    /* May rename the symbols defined below */
+
+
 #ifndef LDAP_THREAD_HAVE_GETCONCURRENCY
 int
 ldap_pvt_thread_get_concurrency ( void )
index d65d9c40b6d3f2cdf00043b96b492f9869a3b737..ba87eaa989175049c9d5c7e465577e32085e20e1 100644 (file)
 #include <ac/errno.h>
 
 #include "ldap-int.h"
-#include "ldap_pvt_thread.h"
+#include "ldap_pvt_thread.h" /* Get the thread interface */
 #include "ldap_queue.h"
+#define LDAP_THREAD_POOL_IMPLEMENTATION
+#include "ldap_thr_debug.h"  /* May rename symbols defined below */
 
 #ifndef LDAP_THREAD_HAVE_TPOOL
 
@@ -50,11 +52,6 @@ typedef struct ldap_int_thread_key_s {
 
 static ldap_pvt_thread_t tid_zero;
 
-#ifdef HAVE_PTHREADS
-#define        TID_EQ(a,b)     pthread_equal((a),(b))
-#else
-#define        TID_EQ(a,b)     ((a) == (b))
-#endif
 static struct {
        ldap_pvt_thread_t id;
        ldap_int_thread_key_t *ctx;
@@ -115,7 +112,7 @@ ldap_int_thread_pool_shutdown ( void )
 
        while ((pool = LDAP_STAILQ_FIRST(&ldap_int_thread_pool_list)) != NULL) {
                LDAP_STAILQ_REMOVE_HEAD(&ldap_int_thread_pool_list, ltp_next);
-               ldap_pvt_thread_pool_destroy( &pool, 0);
+               (ldap_pvt_thread_pool_destroy)(&pool, 0); /* ignore thr_debug macro */
        }
        ldap_pvt_thread_mutex_destroy(&ldap_pvt_thread_pool_mutex);
        return(0);
@@ -277,7 +274,7 @@ ldap_pvt_thread_pool_submit (
                         */
                        TID_HASH(thr, hash);
                        for (rc = hash & (LDAP_MAXTHR-1);
-                               !TID_EQ(thread_keys[rc].id, tid_zero);
+                               !ldap_pvt_thread_equal(thread_keys[rc].id, tid_zero);
                                rc = (rc+1) & (LDAP_MAXTHR-1));
                        thread_keys[rc].id = thr;
                } else {
@@ -437,7 +434,8 @@ ldap_int_thread_pool_wrapper (
 
        /* store pointer to our keys */
        TID_HASH(tid, hash);
-       for (i = hash & (LDAP_MAXTHR-1); !TID_EQ(thread_keys[i].id, tid);
+       for (i = hash & (LDAP_MAXTHR-1);
+                               !ldap_pvt_thread_equal(thread_keys[i].id, tid);
                                i = (i+1) & (LDAP_MAXTHR-1));
        thread_keys[i].ctx = ltc_key;
        keyslot = i;
@@ -661,12 +659,14 @@ void *ldap_pvt_thread_pool_context( )
        int i, hash;
 
        tid = ldap_pvt_thread_self();
-       if ( TID_EQ( tid, ldap_int_main_tid ))
+       if ( ldap_pvt_thread_equal( tid, ldap_int_main_tid ))
                return ldap_int_main_thrctx;
 
        TID_HASH( tid, hash );
-       for (i = hash & (LDAP_MAXTHR-1); !TID_EQ(thread_keys[i].id, tid_zero) &&
-               !TID_EQ(thread_keys[i].id, tid); i = (i+1) & (LDAP_MAXTHR-1));
+       for (i = hash & (LDAP_MAXTHR-1);
+               !ldap_pvt_thread_equal(thread_keys[i].id, tid_zero) &&
+               !ldap_pvt_thread_equal(thread_keys[i].id, tid);
+               i = (i+1) & (LDAP_MAXTHR-1));
 
        return thread_keys[i].ctx;
 }