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