[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: A clean way to detect if a ldap_pvt_thread_mutex is locked (best would be also to know who's the owner of the lock :)
On Fri, 2006-03-31 at 20:09 +0200, Hallvard B Furuseth wrote:
> Or more generally, use my thr_debug.c package and extend
> ldap_debug_thread_cond_t with the thread ID and info about whether the
> mutex is locked. Get thread ID with ldap_pvt_thread_self(), compare
> with ldap_pvt_thread_equal().
What about this? I know for posix threads I could have inspected the
mutex itself (I could specialize the implementation) but this should be
pretty general. When the owner is modified the datum is protected by
the mutex itself; it may not be when the owner is read, though.
p.
Ing. Pierangelo Masarati
Responsabile Open Solution
OpenLDAP Core Team
SysNet s.n.c.
Via Dossi, 8 - 27100 Pavia - ITALIA
http://www.sys-net.it
------------------------------------------
Office: +39.02.23998309
Mobile: +39.333.4963172
Email: pierangelo.masarati@sys-net.it
------------------------------------------
Index: include/ldap_int_thread.h
===================================================================
RCS file: /repo/OpenLDAP/pkg/ldap/include/ldap_int_thread.h,v
retrieving revision 1.16
diff -u -r1.16 ldap_int_thread.h
--- include/ldap_int_thread.h 3 Jan 2006 22:12:06 -0000 1.16
+++ include/ldap_int_thread.h 31 Mar 2006 22:25:32 -0000
@@ -247,6 +247,11 @@
#define LDAP_UINTPTR_T unsigned long
#endif
+#ifndef LDAP_THREAD_DEBUG_NONE
+/* if this definition is not suitable, define per-architecture */
+#define LDAP_THREAD_DEBUG_NONE ((ldap_int_thread_t)(-1))
+#endif /* ! LDAP_THREAD_DEBUG_NONE */
+
typedef union {
unsigned char *ptr;
LDAP_UINTPTR_T num;
@@ -254,6 +259,7 @@
typedef struct {
ldap_int_thread_mutex_t wrapped;
+ ldap_int_thread_t owner;
ldap_debug_usage_info_t usage;
} ldap_debug_thread_mutex_t;
@@ -267,8 +273,25 @@
ldap_debug_usage_info_t usage;
} ldap_debug_thread_rdwr_t;
+#define LDAP_PVT_THREAD_MUTEX_MUSTBELOCKED(mutex) \
+ assert( !ldap_int_thread_equal( (mutex)->owner, LDAP_THREAD_DEBUG_NONE ) )
+#define LDAP_PVT_THREAD_MUTEX_MUSTBESELFLOCKED(mutex) \
+ assert( ldap_int_thread_equal( (mutex)->owner, ldap_pvt_thread_self() ) )
+#define LDAP_PVT_THREAD_MUTEX_MUSTBEUNLOCKED(mutex) \
+ assert( ldap_int_thread_equal( (mutex)->owner, LDAP_THREAD_DEBUG_NONE ) )
+
+LDAP_END_DECL
+
+#else /* ! LDAP_THREAD_DEBUG_WRAP */
+
+LDAP_BEGIN_DECL
+
+#define LDAP_PVT_THREAD_MUTEX_MUSTBELOCKED(mutex)
+#define LDAP_PVT_THREAD_MUTEX_MUSTBESELFLOCKED(mutex)
+#define LDAP_PVT_THREAD_MUTEX_MUSTBEUNLOCKED(mutex)
+
LDAP_END_DECL
-#endif /* LDAP_THREAD_DEBUG_WRAP */
+#endif /* ! LDAP_THREAD_DEBUG_WRAP */
#endif /* _LDAP_INT_THREAD_H */
Index: libraries/libldap/request.c
===================================================================
RCS file: /repo/OpenLDAP/pkg/ldap/libraries/libldap/request.c,v
retrieving revision 1.124
diff -u -r1.124 request.c
--- libraries/libldap/request.c 31 Mar 2006 19:07:53 -0000 1.124
+++ libraries/libldap/request.c 31 Mar 2006 22:25:33 -0000
@@ -751,6 +751,9 @@
ldap_free_request( LDAP *ld, LDAPRequest *lr )
{
LDAPRequest **ttmplr;
+#ifdef LDAP_R_COMPILE
+ LDAP_PVT_THREAD_MUTEX_MUSTBESELFLOCKED( &ld->ld_req_mutex );
+#endif
Debug( LDAP_DEBUG_TRACE, "ldap_free_request (origid %d, msgid %d)\n",
lr->lr_origid, lr->lr_msgid, 0 );
Index: libraries/libldap/result.c
===================================================================
RCS file: /repo/OpenLDAP/pkg/ldap/libraries/libldap/result.c,v
retrieving revision 1.124
diff -u -r1.124 result.c
--- libraries/libldap/result.c 24 Mar 2006 00:18:36 -0000 1.124
+++ libraries/libldap/result.c 31 Mar 2006 22:25:33 -0000
@@ -1159,13 +1179,21 @@
/*
+ * ldap_abandoned
+ *
* return 1 if message msgid is waiting to be abandoned, 0 otherwise
+ *
+ * expects ld_res_mutex to be locked
*/
static int
ldap_abandoned( LDAP *ld, ber_int_t msgid )
{
int i;
+#ifdef LDAP_R_COMPILE
+ LDAP_PVT_THREAD_MUTEX_MUSTBESELFLOCKED( &ld->ld_res_mutex );
+#endif
+
if ( ld->ld_abandoned == NULL )
return( 0 );
@@ -1177,11 +1205,20 @@
}
+/*
+ * ldap_mark_abandoned
+ *
+ * expects ld_res_mutex to be locked
+ */
static int
ldap_mark_abandoned( LDAP *ld, ber_int_t msgid )
{
int i;
+#ifdef LDAP_R_COMPILE
+ LDAP_PVT_THREAD_MUTEX_MUSTBESELFLOCKED( &ld->ld_res_mutex );
+#endif
+
if ( ld->ld_abandoned == NULL )
return( -1 );
Index: libraries/libldap_r/thr_debug.c
===================================================================
RCS file: /repo/OpenLDAP/pkg/ldap/libraries/libldap_r/thr_debug.c,v
retrieving revision 1.2
diff -u -r1.2 thr_debug.c
--- libraries/libldap_r/thr_debug.c 3 Jan 2006 22:12:09 -0000 1.2
+++ libraries/libldap_r/thr_debug.c 31 Mar 2006 22:25:33 -0000
@@ -271,6 +271,9 @@
#ifndef LDAP_THREAD_DEBUG_WRAP
#define WRAPPED(ptr) (ptr)
+#define SETOWNER(ptr)
+#define RESETOWNER(ptr)
+
#define alloc_usage(ptr, msg) ((void) 0)
#define check_usage(ptr, msg) ((void) 0)
#define free_usage(ptr, msg) ((void) 0)
@@ -285,6 +288,13 @@
#else /* LDAP_THREAD_DEBUG_WRAP */
#define WRAPPED(ptr) (&(ptr)->wrapped)
+/* specialize here if assignment is not appropriate */
+#ifndef SETOWNER
+#define SETOWNER(ptr) (ptr)->owner = ldap_pvt_thread_self()
+#endif /* !SETOWNER */
+#ifndef RESETOWNER
+#define RESETOWNER(ptr) (ptr)->owner = LDAP_THREAD_DEBUG_NONE
+#endif /* ! RESETOWNER */
#define INITED_VALUE 0x12345678UL
#define INITED_BYTE_VALUE 0xd5
@@ -705,6 +715,7 @@
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 );
+ RESETOWNER( mutex );
rc = ldap_int_thread_cond_wait( WRAPPED( cond ), WRAPPED( mutex ) );
adjust_count( Idx_locked_mutex, +1 );
ERROR_IF( rc, "ldap_pvt_thread_cond_wait" );
@@ -722,6 +733,7 @@
free_usage( &mutex->usage, "ldap_pvt_thread_mutex_init" );
} else {
adjust_count( Idx_mutex, +1 );
+ RESETOWNER( mutex );
}
return rc;
}
@@ -737,6 +749,7 @@
} else {
free_usage( &mutex->usage, "ldap_pvt_thread_mutex_destroy" );
adjust_count( Idx_mutex, -1 );
+ RESETOWNER( mutex );
}
return rc;
}
@@ -751,6 +764,7 @@
ERROR_IF( rc, "ldap_pvt_thread_mutex_lock" );
} else {
adjust_count( Idx_locked_mutex, +1 );
+ SETOWNER( mutex );
}
return rc;
}
@@ -761,8 +775,10 @@
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 ) {
adjust_count( Idx_locked_mutex, +1 );
+ SETOWNER( mutex );
+ }
return rc;
}
@@ -776,6 +792,7 @@
ERROR_IF( rc, "ldap_pvt_thread_mutex_unlock" );
} else {
adjust_count( Idx_locked_mutex, -1 );
+ RESETOWNER( mutex );
}
return rc;
}