re PR libgcj/12647 ([win32] wait() does not release monitor correctly)
authorMohan Embar <gnustuff@thisiscool.com>
Fri, 31 Oct 2003 03:36:38 +0000 (03:36 +0000)
committerMohan Embar <membar@gcc.gnu.org>
Fri, 31 Oct 2003 03:36:38 +0000 (03:36 +0000)
PR libgcj/12647:
* win32-threads.cc (_Jv_CondWait): Respect mutex's
refcount when releasing and reacquiring it.

From-SVN: r73118

libjava/ChangeLog
libjava/win32-threads.cc

index 7385af65418a024d54508c36435b9a5117e095da..799b490bf00df146edaf16d5f9511f755df61982 100644 (file)
@@ -1,3 +1,9 @@
+2003-10-30  Mohan Embar  <gnustuff@thisiscool.com>
+
+       PR libgcj/12647:
+       * win32-threads.cc (_Jv_CondWait): Respect mutex's
+       refcount when releasing and reacquiring it.
+
 2003-10-30  Mohan Embar  <gnustuff@thisiscool.com>
 
        * win32.cc: (dirExists) Internal helper function to
index 1f3d0c57b22b515e298555ebbb7202014520b0e5..9e3981db3ddcf316e08ed3ad1d9fafbd56f5c7cf 100644 (file)
@@ -126,7 +126,18 @@ _Jv_CondWait(_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint na
   else if (millis == 0) time = INFINITE;
   else time = millis;
 
-  _Jv_MutexUnlock (mu);
+  // Record the current lock depth, so it can be restored
+  // when we reacquire it.
+  int count = mu->refcount;
+  int curcount = count;
+
+  // Call _Jv_MutexUnlock repeatedly until this thread
+  // has completely released the monitor.
+  while (curcount > 0)
+    {  
+      _Jv_MutexUnlock (mu);
+      --curcount;
+    }
 
   // Set up our array of three events:
   // - the auto-reset event (for notify())
@@ -164,7 +175,13 @@ _Jv_CondWait(_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint na
   if (last_waiter)
     ResetEvent (cv->ev[1]);
 
-  _Jv_MutexLock (mu);
+  // Call _Jv_MutexLock repeatedly until the mutex's refcount is the
+  // same as before we originally released it.
+  while (curcount < count)
+    {  
+      _Jv_MutexLock (mu);
+      ++curcount;
+    }
   
   return interrupted ? _JV_INTERRUPTED : 0;
 }