--- old/src/java.desktop/share/classes/java/awt/WaitDispatchSupport.java 2015-03-26 15:03:44.533075600 +0300 +++ new/src/java.desktop/share/classes/java/awt/WaitDispatchSupport.java 2015-03-26 15:03:43.709998700 +0300 @@ -46,9 +46,8 @@ * @since 1.7 */ class WaitDispatchSupport implements SecondaryLoop { - private final static PlatformLogger log = - PlatformLogger.getLogger("java.awt.event.WaitDispatchSupport"); + PlatformLogger.getLogger("java.awt.event.WaitDispatchSupport"); private EventDispatchThread dispatchThread; private EventFilter filter; @@ -65,6 +64,7 @@ private AtomicBoolean keepBlockingEDT = new AtomicBoolean(false); private AtomicBoolean keepBlockingCT = new AtomicBoolean(false); + private AtomicBoolean prematureExit = new AtomicBoolean(false); private static synchronized void initializeTimer() { if (timer == null) { @@ -77,7 +77,7 @@ * serve the given event dispatch thread. * * @param dispatchThread An event dispatch thread that - * should not stop dispatching events while waiting + * should not stop dispatching events while waiting * * @since 1.7 */ @@ -234,50 +234,55 @@ if (log.isLoggable(PlatformLogger.Level.FINEST)) { log.finest("On non-dispatch thread: " + currentThread); } + keepBlockingCT.set(true); synchronized (getTreeLock()) { - if (filter != null) { - dispatchThread.addEventFilter(filter); - } - try { - EventQueue eq = dispatchThread.getEventQueue(); - eq.postEvent(new PeerEvent(this, run, PeerEvent.PRIORITY_EVENT)); - keepBlockingCT.set(true); - if (interval > 0) { - long currTime = System.currentTimeMillis(); - while (keepBlockingCT.get() && - ((extCondition != null) ? extCondition.evaluate() : true) && - (currTime + interval > System.currentTimeMillis())) - { - getTreeLock().wait(interval); + if (keepBlockingEDT.get() && !prematureExit.get()) { + if (filter != null) { + dispatchThread.addEventFilter(filter); + } + try { + EventQueue eq = dispatchThread.getEventQueue(); + eq.postEvent(new PeerEvent(this, run, PeerEvent.PRIORITY_EVENT)); + if (interval > 0) { + long currTime = System.currentTimeMillis(); + while (keepBlockingCT.get() && + ((extCondition != null) ? extCondition.evaluate() : true) && + (currTime + interval > System.currentTimeMillis())) + { + getTreeLock().wait(interval); + } + } else { + while (keepBlockingCT.get() && + ((extCondition != null) ? extCondition.evaluate() : true)) + { + getTreeLock().wait(); + } } - } else { - while (keepBlockingCT.get() && - ((extCondition != null) ? extCondition.evaluate() : true)) - { - getTreeLock().wait(); + if (log.isLoggable(PlatformLogger.Level.FINE)) { + log.fine("waitDone " + keepBlockingEDT.get() + " " + keepBlockingCT.get()); + } + } catch (InterruptedException e) { + if (log.isLoggable(PlatformLogger.Level.FINE)) { + log.fine("Exception caught while waiting: " + e); + } + } finally { + if (filter != null) { + dispatchThread.removeEventFilter(filter); } } - if (log.isLoggable(PlatformLogger.Level.FINE)) { - log.fine("waitDone " + keepBlockingEDT.get() + " " + keepBlockingCT.get()); - } - } catch (InterruptedException e) { - if (log.isLoggable(PlatformLogger.Level.FINE)) { - log.fine("Exception caught while waiting: " + e); - } - } finally { - if (filter != null) { - dispatchThread.removeEventFilter(filter); - } + // If the waiting process has been stopped because of the + // time interval passed or an exception occurred, the state + // should be changed + keepBlockingEDT.set(false); + keepBlockingCT.set(false); + } else { + // We get here when exit called after but happened concurrently + keepBlockingCT.set(false); + prematureExit.set(true); } - // If the waiting process has been stopped because of the - // time interval passed or an exception occurred, the state - // should be changed - keepBlockingEDT.set(false); - keepBlockingCT.set(false); } } - - return true; + return !prematureExit.getAndSet(false); } /** @@ -288,11 +293,26 @@ log.fine("exit(): blockingEDT=" + keepBlockingEDT.get() + ", blockingCT=" + keepBlockingCT.get()); } - if (keepBlockingEDT.compareAndSet(true, false)) { + if(keepBlockingCT.get()) { + // enter() is waiting in non-dispatch thread + synchronized (getTreeLock()) { + keepBlockingEDT.set(false); + prematureExit.set(false); + wakeupEDT(); + return true; + } + } else { + if (keepBlockingEDT.getAndSet(false)) { + prematureExit.set(false); + wakeupEDT(); + return true; + } + // exit() call before enter() + prematureExit.set(true); + // Still need to wake up it can be a concurrent exit() wakeupEDT(); - return true; + return false; } - return false; } private final static Object getTreeLock() { @@ -302,9 +322,13 @@ private final Runnable wakingRunnable = new Runnable() { public void run() { log.fine("Wake up EDT"); - synchronized (getTreeLock()) { - keepBlockingCT.set(false); - getTreeLock().notifyAll(); + keepBlockingEDT.set(false); + if (keepBlockingCT.get()) { + // Notify only if enter() waiting in non-dispatch thread + synchronized (getTreeLock()) { + keepBlockingCT.set(false); + getTreeLock().notifyAll(); + } } log.fine("Wake up EDT done"); }