7177040: Deadlock between PostEventQueue.noEvents, EventQueue.isDispatchThread and SwingUtilities.invokeLater

Reviewed-by: anthony, ant
This commit is contained in:
Oleg Pekhovskiy 2012-07-17 12:59:57 +04:00
parent 80c6175a2a
commit e99cc14fc5

View file

@ -2112,25 +2112,41 @@ class PostEventQueue {
private EventQueueItem queueTail = null; private EventQueueItem queueTail = null;
private final EventQueue eventQueue; private final EventQueue eventQueue;
// For the case when queue is cleared but events are not posted
private volatile boolean isFlushing = false;
PostEventQueue(EventQueue eq) { PostEventQueue(EventQueue eq) {
eventQueue = eq; eventQueue = eq;
} }
public synchronized boolean noEvents() { public synchronized boolean noEvents() {
return queueHead == null; return queueHead == null && !isFlushing;
} }
/* /*
* Continually post pending AWTEvents to the Java EventQueue. The method * Continually post pending AWTEvents to the Java EventQueue. The method
* is synchronized to ensure the flush is completed before a new event * is synchronized to ensure the flush is completed before a new event
* can be posted to this queue. * 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() { public void flush() {
EventQueueItem tempQueue = queueHead; EventQueueItem tempQueue;
queueHead = queueTail = null; synchronized (this) {
while (tempQueue != null) { tempQueue = queueHead;
eventQueue.postEvent(tempQueue.event); queueHead = queueTail = null;
tempQueue = tempQueue.next; isFlushing = true;
}
try {
while (tempQueue != null) {
eventQueue.postEvent(tempQueue.event);
tempQueue = tempQueue.next;
}
}
finally {
isFlushing = false;
} }
} }