src/share/classes/sun/awt/AWTAutoShutdown.java

Print this page




   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.awt;
  27 
  28 import java.awt.AWTEvent;

  29 import java.util.Collections;
  30 import java.util.HashSet;
  31 import java.util.IdentityHashMap;
  32 import java.util.Map;


  33 import sun.util.logging.PlatformLogger;
  34 
  35 /**
  36  * This class is to let AWT shutdown automatically when a user is done
  37  * with AWT. It tracks AWT state using the following parameters:
  38  * <ul>
  39  * <li><code>peerMap</code> - the map between the existing peer objects
  40  *     and their associated targets
  41  * <li><code>toolkitThreadBusy</code> - whether the toolkit thread
  42  *     is waiting for a new native event to appear in its queue
  43  *     or is dispatching an event
  44  * <li><code>busyThreadSet</code> - a set of all the event dispatch
  45  *     threads that are busy at this moment, i.e. those that are not
  46  *     waiting for a new event to appear in their event queue.
  47  * </ul><p>
  48  * AWT is considered to be in ready-to-shutdown state when
  49  * <code>peerMap</code> is empty and <code>toolkitThreadBusy</code>
  50  * is false and <code>busyThreadSet</code> is empty.
  51  * The internal AWTAutoShutdown logic secures that the single non-daemon
  52  * thread (<code>blockerThread</code>) is running when AWT is not in


  64 
  65     /**
  66      * This lock object is used to synchronize shutdown operations.
  67      */
  68     private final Object mainLock = new Object();
  69 
  70     /**
  71      * This lock object is to secure that when a new blocker thread is
  72      * started it will be the first who acquire the main lock after
  73      * the thread that created the new blocker released the main lock
  74      * by calling lock.wait() to wait for the blocker to start.
  75      */
  76     private final Object activationLock = new Object();
  77 
  78     /**
  79      * This set keeps references to all the event dispatch threads that
  80      * are busy at this moment, i.e. those that are not waiting for a
  81      * new event to appear in their event queue.
  82      * Access is synchronized on the main lock object.
  83      */
  84     private final HashSet busyThreadSet = new HashSet(7);
  85 
  86     /**
  87      * Indicates whether the toolkit thread is waiting for a new native
  88      * event to appear or is dispatching an event.
  89      */
  90     private boolean toolkitThreadBusy = false;
  91 
  92     /**
  93      * This is a map between components and their peers.
  94      * we should work with in under activationLock&mainLock lock.
  95      */
  96     private final Map peerMap = new IdentityHashMap();
  97 
  98     /**
  99      * References the alive non-daemon thread that is currently used
 100      * for keeping AWT from exiting.
 101      */
 102     private Thread blockerThread = null;
 103 
 104     /**
 105      * We need this flag to secure that AWT state hasn't changed while
 106      * we were waiting for the safety timeout to pass.
 107      */
 108     private boolean timeoutPassed = false;
 109 
 110     /**
 111      * Once we detect that AWT is ready to shutdown we wait for a certain
 112      * timeout to pass before stopping event dispatch threads.
 113      */
 114     private static final int SAFETY_TIMEOUT = 1000;
 115 
 116     /**


 302                             blockerThread = null;
 303                             break;
 304                         }
 305                         timeoutPassed = true;
 306                         mainLock.wait(SAFETY_TIMEOUT);
 307                     }
 308                 }
 309             } catch (InterruptedException e) {
 310                 interrupted = true;
 311             } finally {
 312                 if (blockerThread == currentThread) {
 313                     blockerThread = null;
 314                 }
 315             }
 316         }
 317         if (!interrupted) {
 318             AppContext.stopEventDispatchThreads();
 319         }
 320     }
 321 

 322     static AWTEvent getShutdownEvent() {
 323         return new AWTEvent(getInstance(), 0) {};

 324     }
 325 
 326     /**
 327      * Creates and starts a new blocker thread. Doesn't return until
 328      * the new blocker thread starts.
 329      */
 330     private void activateBlockerThread() {
 331         Thread thread = new Thread(this, "AWT-Shutdown");
 332         thread.setDaemon(false);
 333         blockerThread = thread;
 334         thread.start();
 335         try {
 336             /* Wait for the blocker thread to start. */
 337             mainLock.wait();
 338         } catch (InterruptedException e) {
 339             System.err.println("AWT blocker activation interrupted:");
 340             e.printStackTrace();
 341         }
 342     }
 343 




   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.awt;
  27 
  28 import java.awt.AWTEvent;
  29 
  30 import java.util.Collections;
  31 import java.util.HashSet;
  32 import java.util.IdentityHashMap;
  33 import java.util.Map;
  34 import java.util.Set;
  35 
  36 import sun.util.logging.PlatformLogger;
  37 
  38 /**
  39  * This class is to let AWT shutdown automatically when a user is done
  40  * with AWT. It tracks AWT state using the following parameters:
  41  * <ul>
  42  * <li><code>peerMap</code> - the map between the existing peer objects
  43  *     and their associated targets
  44  * <li><code>toolkitThreadBusy</code> - whether the toolkit thread
  45  *     is waiting for a new native event to appear in its queue
  46  *     or is dispatching an event
  47  * <li><code>busyThreadSet</code> - a set of all the event dispatch
  48  *     threads that are busy at this moment, i.e. those that are not
  49  *     waiting for a new event to appear in their event queue.
  50  * </ul><p>
  51  * AWT is considered to be in ready-to-shutdown state when
  52  * <code>peerMap</code> is empty and <code>toolkitThreadBusy</code>
  53  * is false and <code>busyThreadSet</code> is empty.
  54  * The internal AWTAutoShutdown logic secures that the single non-daemon
  55  * thread (<code>blockerThread</code>) is running when AWT is not in


  67 
  68     /**
  69      * This lock object is used to synchronize shutdown operations.
  70      */
  71     private final Object mainLock = new Object();
  72 
  73     /**
  74      * This lock object is to secure that when a new blocker thread is
  75      * started it will be the first who acquire the main lock after
  76      * the thread that created the new blocker released the main lock
  77      * by calling lock.wait() to wait for the blocker to start.
  78      */
  79     private final Object activationLock = new Object();
  80 
  81     /**
  82      * This set keeps references to all the event dispatch threads that
  83      * are busy at this moment, i.e. those that are not waiting for a
  84      * new event to appear in their event queue.
  85      * Access is synchronized on the main lock object.
  86      */
  87     private final Set<Thread> busyThreadSet = new HashSet<>(7);
  88 
  89     /**
  90      * Indicates whether the toolkit thread is waiting for a new native
  91      * event to appear or is dispatching an event.
  92      */
  93     private boolean toolkitThreadBusy = false;
  94 
  95     /**
  96      * This is a map between components and their peers.
  97      * we should work with in under activationLock&mainLock lock.
  98      */
  99     private final Map<Object, Object> peerMap = new IdentityHashMap<>();
 100 
 101     /**
 102      * References the alive non-daemon thread that is currently used
 103      * for keeping AWT from exiting.
 104      */
 105     private Thread blockerThread = null;
 106 
 107     /**
 108      * We need this flag to secure that AWT state hasn't changed while
 109      * we were waiting for the safety timeout to pass.
 110      */
 111     private boolean timeoutPassed = false;
 112 
 113     /**
 114      * Once we detect that AWT is ready to shutdown we wait for a certain
 115      * timeout to pass before stopping event dispatch threads.
 116      */
 117     private static final int SAFETY_TIMEOUT = 1000;
 118 
 119     /**


 305                             blockerThread = null;
 306                             break;
 307                         }
 308                         timeoutPassed = true;
 309                         mainLock.wait(SAFETY_TIMEOUT);
 310                     }
 311                 }
 312             } catch (InterruptedException e) {
 313                 interrupted = true;
 314             } finally {
 315                 if (blockerThread == currentThread) {
 316                     blockerThread = null;
 317                 }
 318             }
 319         }
 320         if (!interrupted) {
 321             AppContext.stopEventDispatchThreads();
 322         }
 323     }
 324 
 325     @SuppressWarnings("serial")
 326     static AWTEvent getShutdownEvent() {
 327         return new AWTEvent(getInstance(), 0) {
 328         };
 329     }
 330 
 331     /**
 332      * Creates and starts a new blocker thread. Doesn't return until
 333      * the new blocker thread starts.
 334      */
 335     private void activateBlockerThread() {
 336         Thread thread = new Thread(this, "AWT-Shutdown");
 337         thread.setDaemon(false);
 338         blockerThread = thread;
 339         thread.start();
 340         try {
 341             /* Wait for the blocker thread to start. */
 342             mainLock.wait();
 343         } catch (InterruptedException e) {
 344             System.err.println("AWT blocker activation interrupted:");
 345             e.printStackTrace();
 346         }
 347     }
 348