[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;
 }