You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Klaus Keppler <kl...@informatik.stud.uni-erlangen.de> on 2004/03/05 15:46:36 UTC

[PATCH] apr_thread_cond_wait bug/problem on WIN32

[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 <kl...@informatik.stud.uni-erlangen.de>
Student of Computer Science at University Erlangen-Nurember, Germany



Re: [PATCH] apr_thread_cond_wait bug/problem on WIN32

Posted by Jeff Trawick <tr...@attglobal.net>.
Klaus Keppler wrote:
> [RESENT because I got no response for about two weeks...]

fine to report/discuss here but if no response in that period of time it is 
very likely that it has scrolled off the radar

please report the problem via the bug database at 
http://issues.apache.org/bugzilla/index.html

be sure to put the patch in an attachment and specify the PatchAvailable 
keyword on the PR