Full_Name: Hallvard B Furuseth Version: HEAD OS: URL: Submission from: (NULL) (129.240.6.233) Submitted by: hallvard
send_ldap_ber() has a suspicious-looking waitloop doing this:
if ( ldap_pvt_thread_mutex_trylock( &conn->c_mutex )) { ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex ); ldap_pvt_thread_mutex_lock( &conn->c_write1_mutex );
Unlock does not mean a thread waiting for c_write1_mutex will acquire it immediately. Such a thread may have to wait until it is scheduled, at which time the looping thread has locked the mutex again.
On the Linux box on my desk, a pure unlock-lock loop goes through 50000-100000 iterations before another thread waiting for the lock acquires it. OTOH, on a heavily used box it takes ~50 iterations.
A sched_yield() between the unlock and lock reduces #iterations to 1. No idea if that is the right solution, nor how serious the problem is.
The lock/unlock statements themselves are from result.c rev 1.323, but then with some more locking between them which disappeared in later revisions.
My lock-unlock test program:
#include <pthread.h> #include <sched.h> #include <stdio.h> #include <stdlib.h> #include <sys/select.h>
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; static unsigned count;
static void *waiter(void *arg) { pthread_mutex_lock(&m); printf("Locked after %u iterations.\n", count); exit(0); }
int main() { pthread_t t; pthread_mutex_lock(&m); pthread_create(&t, NULL, waiter, NULL); select(0, NULL, NULL, NULL, &(struct timeval){0, 100000}); for (count = 1 ;; ++count) { pthread_mutex_unlock(&m); pthread_mutex_lock(&m); } }