From cad751250ed4b65b8a2d7e92560354556cc7d4a0 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 1 Apr 2006 19:00:37 +0000 Subject: [PATCH] allow mutex ownership detection (thanks to Hallvard) --- include/ldap_int_thread.h | 6 +++++ include/ldap_pvt_thread.h | 6 +++++ libraries/libldap_r/thr_debug.c | 43 ++++++++++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/include/ldap_int_thread.h b/include/ldap_int_thread.h index b072ae2b82..39bc4228ca 100644 --- a/include/ldap_int_thread.h +++ b/include/ldap_int_thread.h @@ -255,6 +255,7 @@ typedef union { typedef struct { ldap_int_thread_mutex_t wrapped; ldap_debug_usage_info_t usage; + ldap_int_thread_t owner; } ldap_debug_thread_mutex_t; typedef struct { @@ -267,6 +268,11 @@ typedef struct { ldap_debug_usage_info_t usage; } ldap_debug_thread_rdwr_t; +#define LDAP_INT_THREAD_ASSERT_MUTEX_OWNER(mutex) \ + assert( ldap_debug_thread_mutex_owner( mutex ) ) +LDAP_F(int) ldap_debug_thread_mutex_owner LDAP_P(( + ldap_debug_thread_mutex_t * )); + LDAP_END_DECL #endif /* LDAP_THREAD_DEBUG_WRAP */ diff --git a/include/ldap_pvt_thread.h b/include/ldap_pvt_thread.h index 4b67d20924..3f2d48fb11 100644 --- a/include/ldap_pvt_thread.h +++ b/include/ldap_pvt_thread.h @@ -125,6 +125,12 @@ 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 )); +#ifdef LDAP_INT_THREAD_ASSERT_MUTEX_OWNER +#define LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER LDAP_INT_THREAD_ASSERT_MUTEX_OWNER +#else +#define LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER(mutex) ((void) 0) +#endif + LDAP_F( int ) ldap_pvt_thread_rdwr_init LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp)); diff --git a/libraries/libldap_r/thr_debug.c b/libraries/libldap_r/thr_debug.c index fac64616eb..be9079f6b8 100644 --- a/libraries/libldap_r/thr_debug.c +++ b/libraries/libldap_r/thr_debug.c @@ -271,6 +271,11 @@ exit_thread_message( const ldap_pvt_thread_t thread ) #ifndef LDAP_THREAD_DEBUG_WRAP #define WRAPPED(ptr) (ptr) +#define SET_OWNER(ptr) ((void) 0) +#define RESET_OWNER(ptr) ((void) 0) +#define ASSERT_OWNER(ptr) ((void) 0) +#define ASSERT_NO_OWNER(ptr) ((void) 0) + #define alloc_usage(ptr, msg) ((void) 0) #define check_usage(ptr, msg) ((void) 0) #define free_usage(ptr, msg) ((void) 0) @@ -284,7 +289,28 @@ exit_thread_message( const ldap_pvt_thread_t thread ) #else /* LDAP_THREAD_DEBUG_WRAP */ +/* Specialize this if initializer is not appropriate. */ +/* The ASSERT_NO_OWNER() definition may also need an override. */ +#ifndef LDAP_DEBUG_THREAD_NONE +#define LDAP_DEBUG_THREAD_NONE { -1 } /* "no thread" ldap_int_thread_t value */ +#endif + +static const ldap_int_thread_t ldap_debug_thread_none = LDAP_DEBUG_THREAD_NONE; + +int +ldap_debug_thread_mutex_owner( ldap_pvt_thread_mutex_t *mutex ) +{ + return ldap_pvt_thread_equal( mutex->owner, ldap_pvt_thread_self() ); +} + #define WRAPPED(ptr) (&(ptr)->wrapped) +#define SET_OWNER(ptr) ((ptr)->owner = ldap_pvt_thread_self()) +#define RESET_OWNER(ptr) ((ptr)->owner = ldap_debug_thread_none) +#define ASSERT_OWNER LDAP_INT_THREAD_ASSERT_MUTEX_OWNER +#ifndef ASSERT_NO_OWNER +#define ASSERT_NO_OWNER(ptr) \ + assert( ldap_int_thread_equal( (ptr)->owner, ldap_debug_thread_none ) ) +#endif #define INITED_VALUE 0x12345678UL #define INITED_BYTE_VALUE 0xd5 @@ -705,7 +731,11 @@ ldap_pvt_thread_cond_wait( 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 ); + ASSERT_OWNER( mutex ); + RESET_OWNER( mutex ); /* Breaks if this thread did not own the mutex */ rc = ldap_int_thread_cond_wait( WRAPPED( cond ), WRAPPED( mutex ) ); + ASSERT_NO_OWNER( mutex ); + SET_OWNER( mutex ); adjust_count( Idx_locked_mutex, +1 ); ERROR_IF( rc, "ldap_pvt_thread_cond_wait" ); return rc; @@ -721,6 +751,7 @@ ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex ) ERROR( rc, "ldap_pvt_thread_mutex_init" ); free_usage( &mutex->usage, "ldap_pvt_thread_mutex_init" ); } else { + RESET_OWNER( mutex ); adjust_count( Idx_mutex, +1 ); } return rc; @@ -731,11 +762,14 @@ ldap_pvt_thread_mutex_destroy( ldap_pvt_thread_mutex_t *mutex ) { int rc; check_usage( &mutex->usage, "ldap_pvt_thread_mutex_destroy" ); + ASSERT_NO_OWNER( mutex ); rc = ldap_int_thread_mutex_destroy( WRAPPED( mutex ) ); if( rc ) { ERROR( rc, "ldap_pvt_thread_mutex_destroy" ); + /* mutex->owner may now be scrambled, sorry */ } else { free_usage( &mutex->usage, "ldap_pvt_thread_mutex_destroy" ); + RESET_OWNER( mutex ); adjust_count( Idx_mutex, -1 ); } return rc; @@ -750,6 +784,8 @@ ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex ) if( rc ) { ERROR_IF( rc, "ldap_pvt_thread_mutex_lock" ); } else { + ASSERT_NO_OWNER( mutex ); + SET_OWNER( mutex ); adjust_count( Idx_locked_mutex, +1 ); } return rc; @@ -761,8 +797,11 @@ 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 ) + if( rc == 0 ) { + ASSERT_NO_OWNER( mutex ); + SET_OWNER( mutex ); adjust_count( Idx_locked_mutex, +1 ); + } return rc; } @@ -771,6 +810,8 @@ ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex ) { int rc; check_usage( &mutex->usage, "ldap_pvt_thread_mutex_unlock" ); + ASSERT_OWNER( mutex ); + RESET_OWNER( mutex ); /* Breaks if this thread did not own the mutex */ rc = ldap_int_thread_mutex_unlock( WRAPPED( mutex ) ); if( rc ) { ERROR_IF( rc, "ldap_pvt_thread_mutex_unlock" ); -- 2.39.5