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.