h.b.furuseth@usit.uio.no wrote:
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.
This code has changed in HEAD. Closing this ITS.
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); } }