< prev index next >

src/java.desktop/share/classes/java/awt/WaitDispatchSupport.java

Print this page

        

@@ -44,11 +44,10 @@
  * @author Anton Tarasov, Artem Ananiev
  *
  * @since 1.7
  */
 class WaitDispatchSupport implements SecondaryLoop {
-
     private final static PlatformLogger log =
         PlatformLogger.getLogger("java.awt.event.WaitDispatchSupport");
 
     private EventDispatchThread dispatchThread;
     private EventFilter filter;

@@ -63,10 +62,11 @@
     // shared timer up and running
     private TimerTask timerTask;
 
     private AtomicBoolean keepBlockingEDT = new AtomicBoolean(false);
     private AtomicBoolean keepBlockingCT = new AtomicBoolean(false);
+    private AtomicBoolean afterExit = new AtomicBoolean(false);
 
     private static synchronized void initializeTimer() {
         if (timer == null) {
             timer = new Timer("AWT-WaitDispatchSupport-Timer", true);
         }

@@ -112,11 +112,11 @@
                     log.finest("evaluate(): blockingEDT=" + keepBlockingEDT.get() +
                                ", blockingCT=" + keepBlockingCT.get());
                 }
                 boolean extEvaluate =
                     (extCondition != null) ? extCondition.evaluate() : true;
-                if (!keepBlockingEDT.get() || !extEvaluate) {
+                if (!keepBlockingEDT.get() || !extEvaluate || afterExit.get()) {
                     if (timerTask != null) {
                         timerTask.cancel();
                         timerTask = null;
                     }
                     return false;

@@ -172,10 +172,15 @@
 
         if (!keepBlockingEDT.compareAndSet(false, true)) {
             log.fine("The secondary loop is already running, aborting");
             return false;
         }
+        try {
+            if (afterExit.get()) {
+                log.fine("Exit was called already, aborting");
+                return false;
+            }
 
         final Runnable run = new Runnable() {
             public void run() {
                 log.fine("Starting a new event pump");
                 if (filter == null) {

@@ -232,18 +237,19 @@
             });
         } else {
             if (log.isLoggable(PlatformLogger.Level.FINEST)) {
                 log.finest("On non-dispatch thread: " + currentThread);
             }
+                keepBlockingCT.set(true);
             synchronized (getTreeLock()) {
+                    if (afterExit.get()) return false;
                 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()))

@@ -267,34 +273,33 @@
                 } 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);
             }
         }
-
         return true;
     }
+        finally {
+            keepBlockingEDT.set(false);
+            keepBlockingCT.set(false);
+            afterExit.set(false);
+        }
+    }
 
     /**
      * {@inheritDoc}
      */
     public boolean exit() {
         if (log.isLoggable(PlatformLogger.Level.FINE)) {
             log.fine("exit(): blockingEDT=" + keepBlockingEDT.get() +
                      ", blockingCT=" + keepBlockingCT.get());
         }
-        if (keepBlockingEDT.compareAndSet(true, false)) {
+        afterExit.set(true);
+        boolean noEnter = !keepBlockingEDT.getAndSet(false);
             wakeupEDT();
-            return true;
-        }
-        return false;
+        return noEnter;
     }
 
     private final static Object getTreeLock() {
         return Component.LOCK;
     }
< prev index next >