changeset 5206:df945ef30444 jdk7u8-b01

7177040: Deadlock between PostEventQueue.noEvents, EventQueue.isDispatchThread and SwingUtilities.invokeLater Reviewed-by: art, ant
author bagiras
date Wed, 25 Jul 2012 14:47:10 +0400
parents 250ce303f42d
children 797aed840eb1 dd1e513c05b8
files src/share/classes/sun/awt/SunToolkit.java
diffstat 1 files changed, 23 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/awt/SunToolkit.java	Sun Apr 22 21:22:17 2012 +0100
+++ b/src/share/classes/sun/awt/SunToolkit.java	Wed Jul 25 14:47:10 2012 +0400
@@ -2096,25 +2096,41 @@
     private EventQueueItem queueTail = null;
     private final EventQueue eventQueue;
 
+    // For the case when queue is cleared but events are not posted
+    private volatile boolean isFlushing = false;
+
     PostEventQueue(EventQueue eq) {
         eventQueue = eq;
     }
 
     public synchronized boolean noEvents() {
-        return queueHead == null;
+        return queueHead == null && !isFlushing;
     }
 
     /*
      * Continually post pending AWTEvents to the Java EventQueue. The method
      * is synchronized to ensure the flush is completed before a new event
      * can be posted to this queue.
+     *
+     * 7177040: The method couldn't be wholly synchronized because of calls
+     * of EventQueue.postEvent() that uses pushPopLock, otherwise it could
+     * potentially lead to deadlock
      */
-    public synchronized void flush() {
-        EventQueueItem tempQueue = queueHead;
-        queueHead = queueTail = null;
-        while (tempQueue != null) {
-            eventQueue.postEvent(tempQueue.event);
-            tempQueue = tempQueue.next;
+    public void flush() {
+        EventQueueItem tempQueue;
+        synchronized (this) {
+            tempQueue = queueHead;
+            queueHead = queueTail = null;
+            isFlushing = (tempQueue != null);
+        }
+        try {
+            while (tempQueue != null) {
+                eventQueue.postEvent(tempQueue.event);
+                tempQueue = tempQueue.next;
+            }
+        }
+        finally {
+            isFlushing = false;
         }
     }