this sounds awfully familiar... while I'm still working on getting a win32 build up and running, can somebody try the hook order thing with this patch?
thanks. --Geoff -------- Original Message -------- Subject: [PATCH] apr_thread_cond_wait bug/problem on WIN32 Date: Fri, 05 Mar 2004 15:46:36 +0100 From: Klaus Keppler <[EMAIL PROTECTED]> To: [EMAIL PROTECTED] [RESENT because I got no response for about two weeks...] Hello, having spent several hours on one problem only occuring on WIN32 platform I found following bug(?) with locks/win32/thread_cond.c. In my application I use the function apr_thread_cond_wait in a very similar context like httpd2's worker-mpm (fdqueue.c -> ap_queue_pop). Heavy load tests (using apache's ab) worked well under linux, but on win32 I experienced deadlocks after some seconds. Debugging brought me to the source of apr_thread_cond_wait(); as you can see the function "apr_thread_mutex_unlock(mutex)" is called every time the while(1)-loop is run. I think this shouldn't be a problem in general (since an unlocked mutex can't be unlocked once more), but at least for *me* it *did* cause trouble. And I am no windows guru so I don't know if/how windows bothers about multiple unlocking. After changing the code to unlock the mutex only once everything worked very fine. :-) I tested the patch with Win2K. Without patch, my application ran (with 2 worker threads) only up to 20 loops before ending in an deadlock; now I tested 200.000 loops without problems. Btw: another approach would be to add a counter to every mutex and ignore unlock calls when counter==0. Would this make sense? Klaus --- locks/win32/thread_cond-old.c Mon Feb 23 11:56:45 2004 +++ locks/win32/thread_cond.c Mon Feb 23 12:01:46 2004 @@ -85,6 +85,8 @@ { DWORD res; + int unlock_once = 1; + while (1) { res = WaitForSingleObject(cond->mutex, INFINITE); if (res != WAIT_OBJECT_0) { @@ -93,7 +95,10 @@ cond->num_waiting++; ReleaseMutex(cond->mutex); - apr_thread_mutex_unlock(mutex); + if (unlock_once) { + unlock_once = 0; + apr_thread_mutex_unlock(mutex); + } res = WaitForSingleObject(cond->event, INFINITE); cond->num_waiting--; if (res != WAIT_OBJECT_0) { @@ -125,6 +130,8 @@ DWORD res; DWORD timeout_ms = (DWORD) apr_time_as_msec(timeout); + int unlock_once = 1; + while (1) { res = WaitForSingleObject(cond->mutex, timeout_ms); if (res != WAIT_OBJECT_0) { @@ -136,7 +143,10 @@ cond->num_waiting++; ReleaseMutex(cond->mutex); - apr_thread_mutex_unlock(mutex); + if (unlock_once) { + unlock_once = 0; + apr_thread_mutex_unlock(mutex); + } res = WaitForSingleObject(cond->event, timeout_ms); cond->num_waiting--; if (res != WAIT_OBJECT_0) { -- Klaus Keppler <[EMAIL PROTECTED]> Student of Computer Science at University Erlangen-Nurember, Germany --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]