EventQueue.java (pop): Prevent racing condition to add events to the queue out of...
authorFernando Nasser <fnasser@redhat.com>
Mon, 19 Jan 2004 17:38:36 +0000 (17:38 +0000)
committerFernando Nasser <fnasser@gcc.gnu.org>
Mon, 19 Jan 2004 17:38:36 +0000 (17:38 +0000)
        * java/awt/EventQueue.java (pop): Prevent racing condition to add
        events to the queue out of order by acquiring locks in the proper
        order and not by releasing one before acquiring the other.

From-SVN: r76161

libjava/ChangeLog
libjava/java/awt/EventQueue.java

index afe9565655bf0a0bb3cb73713b1f55976d0ce422..2b34a94f9e1bbb9e20851024d302b1a65f1cd863 100644 (file)
@@ -1,3 +1,9 @@
+2004-01-19  Fernando Nasser  <fnasser@redhat.com>
+
+       * java/awt/EventQueue.java (pop): Prevent racing condition to add
+       events to the queue out of order by acquiring locks in the proper
+       order and not by releasing one before acquiring the other.
+
 2004-01-19  Fernando Nasser  <fnasser@redhat.com>
 
        * gnu/java/awt/peer/gtk/TestAWT.java (DialogWindow): Make text not
index 4cb0703ec6235bc5c5740b89e9c9c28579667063..7df40edee3869e24ee6f5d4f988ce95d76d8fd7b 100644 (file)
@@ -358,32 +358,34 @@ public class EventQueue
     if (prev == null)
       throw new EmptyStackException();
 
-    // Don't synchronize both this and prev at the same time, or deadlock could
-    // occur.
+    /* The order is important here, we must get the prev lock first,
+       or deadlock could occur as callers usually get here following
+       prev's next pointer, and thus obtain prev's lock before trying
+       to get this lock. */
     synchronized (prev)
       {
         prev.next = next;
         if (next != null)
           next.prev = prev;
-      }
 
-    synchronized (this)
-      {
-        int i = next_out;
-        while (i != next_in)
+        synchronized (this)
           {
-            prev.postEvent(queue[i]);
-            next_out = i;
-            if (++i == queue.length)
-              i = 0;
-          }
-       // Empty the queue so it can be reused
-       next_in = 0;
-       next_out = 0;
+            int i = next_out;
+            while (i != next_in)
+              {
+                prev.postEvent(queue[i]);
+                next_out = i;
+                if (++i == queue.length)
+                  i = 0;
+              }
+           // Empty the queue so it can be reused
+           next_in = 0;
+           next_out = 0;
 
-        // Tell our EventDispatchThread that it can end execution
-        dispatchThread.interrupt ();
-       dispatchThread = null;
+            // Tell our EventDispatchThread that it can end execution
+            dispatchThread.interrupt ();
+           dispatchThread = null;
+          }
       }
   }