src/share/classes/sun/awt/SunToolkit.java
Print this page
*** 504,547 ****
}
}, PeerEvent.ULTIMATE_PRIORITY_EVENT);
postEvent(targetToAppContext(e.getSource()), pe);
}
- protected static final Lock flushLock = new ReentrantLock();
- private static boolean isFlushingPendingEvents = false;
-
/*
* Flush any pending events which haven't been posted to the AWT
* EventQueue yet.
*/
public static void flushPendingEvents() {
- flushLock.lock();
- try {
- // Don't call flushPendingEvents() recursively
- if (!isFlushingPendingEvents) {
- isFlushingPendingEvents = true;
AppContext appContext = AppContext.getAppContext();
! PostEventQueue postEventQueue =
! (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
! if (postEventQueue != null) {
! postEventQueue.flush();
! }
! }
! } finally {
! isFlushingPendingEvents = false;
! flushLock.unlock();
! }
}
! public static boolean isPostEventQueueEmpty() {
! AppContext appContext = AppContext.getAppContext();
PostEventQueue postEventQueue =
(PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
if (postEventQueue != null) {
! return postEventQueue.noEvents();
! } else {
! return true;
}
}
/*
* Execute a chunk of code on the Java event handler thread for the
--- 504,532 ----
}
}, PeerEvent.ULTIMATE_PRIORITY_EVENT);
postEvent(targetToAppContext(e.getSource()), pe);
}
/*
* Flush any pending events which haven't been posted to the AWT
* EventQueue yet.
*/
public static void flushPendingEvents() {
AppContext appContext = AppContext.getAppContext();
! flushPendingEvents(appContext);
}
! /*
! * Flush the PostEventQueue for the right AppContext.
! * The default flushPendingEvents only flushes the thread-local context,
! * which is not always correct, c.f. 3746956
! */
! public static void flushPendingEvents(AppContext appContext) {
PostEventQueue postEventQueue =
(PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
if (postEventQueue != null) {
! postEventQueue.flush();
}
}
/*
* Execute a chunk of code on the Java event handler thread for the
*** 2043,2087 ****
class PostEventQueue {
private EventQueueItem queueHead = null;
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 && !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 void flush() {
EventQueueItem tempQueue;
synchronized (this) {
tempQueue = queueHead;
queueHead = queueTail = null;
- isFlushing = true;
}
- try {
while (tempQueue != null) {
eventQueue.postEvent(tempQueue.event);
tempQueue = tempQueue.next;
}
}
finally {
! isFlushing = false;
}
}
/*
* Enqueue an AWTEvent to be posted to the Java EventQueue.
--- 2028,2096 ----
class PostEventQueue {
private EventQueueItem queueHead = null;
private EventQueueItem queueTail = null;
private final EventQueue eventQueue;
! private Thread flushThread = null;
PostEventQueue(EventQueue eq) {
eventQueue = eq;
}
/*
* 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 void flush() {
+
+ Thread newThread = Thread.currentThread();
+
+ try {
EventQueueItem tempQueue;
synchronized (this) {
+ // Avoid method recursion
+ if (newThread == flushThread) {
+ newThread = null;
+ return;
+ }
+ // Wait for other threads' flushing
+ while (flushThread != null) {
+ wait();
+ }
+ // Skip everything if queue is empty
+ if (queueHead == null) {
+ notifyAll();
+ return;
+ }
+ // Remember flushing thread
+ flushThread = newThread;
+
tempQueue = queueHead;
queueHead = queueTail = null;
}
while (tempQueue != null) {
eventQueue.postEvent(tempQueue.event);
tempQueue = tempQueue.next;
}
}
+ catch (InterruptedException e) {
+ // Couldn't allow exception go up, so at least recover the flag
+ newThread.interrupt();
+ }
finally {
! synchronized (this) {
! // Forget flushing thread, inform other pending threads
! if (newThread == flushThread) {
! flushThread = null;
! notifyAll();
! }
! }
}
}
/*
* Enqueue an AWTEvent to be posted to the Java EventQueue.