jdk/src/share/classes/java/lang/Shutdown.java
changeset 2277 445a331b4a8b
parent 2 90ce3da70b43
child 2703 acd4d6a53e3e
equal deleted inserted replaced
2184:0c19e3499374 2277:445a331b4a8b
    23  * have any questions.
    23  * have any questions.
    24  */
    24  */
    25 
    25 
    26 package java.lang;
    26 package java.lang;
    27 
    27 
    28 import java.util.ArrayList;
       
    29 
       
    30 
    28 
    31 /**
    29 /**
    32  * Package-private utility class containing data structures and logic
    30  * Package-private utility class containing data structures and logic
    33  * governing the virtual-machine shutdown sequence.
    31  * governing the virtual-machine shutdown sequence.
    34  *
    32  *
    45     private static int state = RUNNING;
    43     private static int state = RUNNING;
    46 
    44 
    47     /* Should we run all finalizers upon exit? */
    45     /* Should we run all finalizers upon exit? */
    48     private static boolean runFinalizersOnExit = false;
    46     private static boolean runFinalizersOnExit = false;
    49 
    47 
    50     /* The set of registered, wrapped hooks, or null if there aren't any */
    48     // The system shutdown hooks are registered with a predefined slot.
    51     private static ArrayList<Runnable> hooks = new ArrayList<Runnable>();
    49     // The list of shutdown hooks is as follows:
       
    50     // (0) Console restore hook
       
    51     // (1) Application hooks
       
    52     // (2) DeleteOnExit hook
       
    53     private static final int MAX_SYSTEM_HOOKS = 10;
       
    54     private static final Runnable[] hooks = new Runnable[MAX_SYSTEM_HOOKS];
    52 
    55 
    53     /* The preceding static fields are protected by this lock */
    56     /* The preceding static fields are protected by this lock */
    54     private static class Lock { };
    57     private static class Lock { };
    55     private static Object lock = new Lock();
    58     private static Object lock = new Lock();
    56 
    59 
    66 
    69 
    67 
    70 
    68     /* Add a new shutdown hook.  Checks the shutdown state and the hook itself,
    71     /* Add a new shutdown hook.  Checks the shutdown state and the hook itself,
    69      * but does not do any security checks.
    72      * but does not do any security checks.
    70      */
    73      */
    71     static void add(Runnable hook) {
    74     static void add(int slot, Runnable hook) {
    72         synchronized (lock) {
    75         synchronized (lock) {
    73             if (state > RUNNING)
    76             if (state > RUNNING)
    74                 throw new IllegalStateException("Shutdown in progress");
    77                 throw new IllegalStateException("Shutdown in progress");
    75 
    78 
    76             hooks.add(hook);
    79             if (hooks[slot] != null)
    77         }
    80                 throw new InternalError("Shutdown hook at slot " + slot + " already registered");
    78     }
    81 
    79 
    82             hooks[slot] = hook;
    80 
    83         }
    81     /* Remove a previously-registered hook.  Like the add method, this method
    84     }
    82      * does not do any security checks.
       
    83      */
       
    84     static boolean remove(Runnable hook) {
       
    85         synchronized (lock) {
       
    86             if (state > RUNNING)
       
    87                 throw new IllegalStateException("Shutdown in progress");
       
    88             if (hook == null) throw new NullPointerException();
       
    89             if (hooks == null) {
       
    90                 return false;
       
    91             } else {
       
    92                 return hooks.remove(hook);
       
    93             }
       
    94         }
       
    95     }
       
    96 
       
    97 
    85 
    98     /* Run all registered shutdown hooks
    86     /* Run all registered shutdown hooks
    99      */
    87      */
   100     private static void runHooks() {
    88     private static void runHooks() {
   101         /* We needn't bother acquiring the lock just to read the hooks field,
    89         /* We needn't bother acquiring the lock just to read the hooks field,
   102          * since the hooks can't be modified once shutdown is in progress
    90          * since the hooks can't be modified once shutdown is in progress
   103          */
    91          */
   104         for (Runnable hook : hooks) {
    92         for (Runnable hook : hooks) {
   105             try {
    93             try {
   106                 hook.run();
    94                 if (hook != null) hook.run();
   107             } catch(Throwable t) {
    95             } catch(Throwable t) {
   108                 if (t instanceof ThreadDeath) {
    96                 if (t instanceof ThreadDeath) {
   109                     ThreadDeath td = (ThreadDeath)t;
    97                     ThreadDeath td = (ThreadDeath)t;
   110                     throw td;
    98                     throw td;
   111                 }
    99                 }