This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[win32] notifyAll also notifying following wait calls


Hey list

win32-threads.cc has a thread race for notifyAll() and wait(). Test.java should actually deadlock, but sometimes it doesn't because the second wait increments blocked_count before the event is reset and thus will also be called.
My proposed patch moves the reset of the event into notifyAll because this way, the even is reset just after all waiting threads have been notified instead of when the last waiting thread has started working again. As I said, there might be a new thread which called wait() before the last waiting thread would reset the event.


Was I more or less clear? I'd really appreciate if a couple of persons could take a look at the problem and my proposed solution because it's always a good thing to triple check concurrency problems...


thanks Marco
public class Test
{
	private static final Object mainLock = new Object();

	public static void main(String[] args) throws Exception
	{
		new Thread()
		{
			public void run()
			{
				synchronized(mainLock)
				{
					try
					{
						System.out.println("wait 1 start");
						mainLock.wait(); // might be notified
						System.out.println("wait 1 done");
					} catch (InterruptedException e)
					{
						e.printStackTrace();
					}
				}
			}
		}.start();

		new Thread()
		{
			public void run()
			{
				synchronized(mainLock)
				{
					mainLock.notifyAll();

					try
					{
						System.out.println("wait 2 start");
						mainLock.wait(); // not allowed to be notified 
						System.out.println("wait 2 done! Not allowed!");
					} catch (InterruptedException e)
					{
						e.printStackTrace();
					}
				}
			}
		}.start();
	}
}
Index: win32-threads.cc
===================================================================
--- win32-threads.cc	(revision 121541)
+++ win32-threads.cc	(working copy)
@@ -177,14 +177,8 @@
 
   EnterCriticalSection(&cv->count_mutex);
   cv->blocked_count--;
-  // If we were unblocked by the second event (the broadcast one)
-  // and nobody is left, then reset the event.
-  int last_waiter = (rval == (WAIT_OBJECT_0 + 1)) && (cv->blocked_count == 0);
   LeaveCriticalSection(&cv->count_mutex);
 
-  if (last_waiter)
-    ResetEvent (cv->ev[1]);
-
   // Call _Jv_MutexLock repeatedly until the mutex's refcount is the
   // same as before we originally released it.
   while (curcount < count)
@@ -248,7 +242,10 @@
   LeaveCriticalSection (&cv->count_mutex);
 
   if (somebody_is_blocked)
-    SetEvent (cv->ev[1]);
+    {
+      SetEvent (cv->ev[1]); // notify all waiting threads
+      ResetEvent (cv->ev[1]); // reset the notification
+    }
 
   return 0;
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]