src/share/classes/java/awt/EventQueue.java

Print this page

        

@@ -37,15 +37,16 @@
 
 import java.util.EmptyStackException;
 import sun.util.logging.PlatformLogger;
 
 import sun.awt.AppContext;
+import sun.awt.AWTAccessor;
 import sun.awt.AWTAutoShutdown;
+import sun.awt.AWTInterruptedException;
 import sun.awt.PeerEvent;
 import sun.awt.SunToolkit;
 import sun.awt.EventQueueItem;
-import sun.awt.AWTAccessor;
 
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.atomic.AtomicInteger;
 

@@ -1036,19 +1037,21 @@
          * be valid at that point.
          */
         pushPopLock.lock();
         try {
             if (edt == dispatchThread) {
+                if (peekEvent() != null || !SunToolkit.isPostEventQueueEmpty()) {
+                    if (!forceDetach) {
                 /*
-                 * Don't detach the thread if any events are pending. Not
-                 * sure if it's a possible scenario, though.
-                 *
                  * Fix for 4648733. Check both the associated java event
                  * queue and the PostEventQueue.
                  */
-                if (!forceDetach && (peekEvent() != null) || !SunToolkit.isPostEventQueueEmpty()) {
                     return false;
+                    } else {
+                        // 7162144 - derail pending events
+                        removeAllEvents();
+                    }
                 }
                 dispatchThread = null;
             }
             AWTAutoShutdown.getInstance().notifyThreadFree(edt);
             return true;

@@ -1126,10 +1129,43 @@
         } finally {
             pushPopLock.unlock();
         }
     }
 
+    private void removeAllEvents() {
+        SunToolkit.flushPendingEvents();
+        pushPopLock.lock();
+        try {
+            for (int i = 0; i < NUM_PRIORITIES; i++) {
+                EventQueueItem entry = queues[i].head;
+                EventQueueItem prev = null;
+                while (entry != null) {
+                    if (entry.event instanceof InvocationEvent) {
+                        AWTAccessor.getInvocationEventAccessor().
+                            dispose((InvocationEvent)entry.event);
+                    }
+                    if (entry.event instanceof SequencedEvent) {
+                        ((SequencedEvent)entry.event).dispose();
+                    }
+                    if (entry.event instanceof SentEvent) {
+                        ((SentEvent)entry.event).dispose();
+                    }
+                    if (prev == null) {
+                        queues[i].head = entry.next;
+                    } else {
+                        prev.next = entry.next;
+                    }
+                    uncacheEQItem(entry);
+                    entry = entry.next;
+                }
+                queues[i].tail = prev;
+            }
+        } finally {
+            pushPopLock.unlock();
+        }
+    }
+
     static void setCurrentEventAndMostRecentTime(AWTEvent e) {
         Toolkit.getEventQueue().setCurrentEventAndMostRecentTimeImpl(e);
     }
     private void setCurrentEventAndMostRecentTimeImpl(AWTEvent e) {
         pushPopLock.lock();

@@ -1233,13 +1269,17 @@
             }
         }
 
         Throwable eventThrowable = event.getThrowable();
         if (eventThrowable != null) {
+            if (eventThrowable instanceof AWTInterruptedException) {
+                throw new InterruptedException(eventThrowable.getMessage());
+            } else {
             throw new InvocationTargetException(eventThrowable);
         }
     }
+    }
 
     /*
      * Called from PostEventQueue.postEvent to notify that a new event
      * appeared. First it proceeds to the EventQueue on the top of the
      * stack, then notifies the associated dispatch thread if it exists