• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2  *
3  * This program and the accompanying materials are made available under
4  * the terms of the Common Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
6  *
7  * $Id: ExitHookManager.java,v 1.1.1.1 2004/05/09 16:57:58 vlad_r Exp $
8  */
9 package com.vladium.util.exit;
10 
11 import java.util.HashMap;
12 import java.util.Map;
13 
14 import com.vladium.util.IJREVersion;
15 import com.vladium.util.Property;
16 import com.vladium.emma.IAppConstants;
17 
18 // ----------------------------------------------------------------------------
19 /**
20  * @author Vlad Roubtsov, (C) 2003
21  */
22 public
23 abstract class ExitHookManager implements IJREVersion
24 {
25     // public: ................................................................
26 
27     // TOTO: handle thread groups as well?
28 
addExitHook(Runnable runnable)29     public abstract boolean addExitHook (Runnable runnable);
removeExitHook(Runnable runnable)30     public abstract boolean removeExitHook (Runnable runnable);
31 
getSingleton()32     public static synchronized ExitHookManager getSingleton ()
33     {
34         if (s_singleton == null)
35         {
36             if (JRE_1_3_PLUS)
37             {
38                 s_singleton = new JRE13ExitHookManager ();
39             }
40             else
41             {
42                 throw new UnsupportedOperationException ("no shutdown hook manager available [JVM: " + Property.getSystemFingerprint () + "]");
43             }
44         }
45 
46         return s_singleton;
47     }
48 
49     // protected: .............................................................
50 
51 
ExitHookManager()52     protected ExitHookManager () {}
53 
54     // package: ...............................................................
55 
56     // private: ...............................................................
57 
58 
59     private static final class JRE13ExitHookManager extends ExitHookManager
60     {
addExitHook(final Runnable runnable)61         public synchronized boolean addExitHook (final Runnable runnable)
62         {
63             if ((runnable != null) && ! m_exitThreadMap.containsKey (runnable))
64             {
65                 final Thread exitThread = new Thread (runnable, IAppConstants.APP_NAME + " shutdown handler thread");
66 
67                 try
68                 {
69                     Runtime.getRuntime ().addShutdownHook (exitThread);
70                     m_exitThreadMap.put (runnable, exitThread); // TODO: use identity here
71 
72                     return true;
73                 }
74                 catch (Exception e)
75                 {
76                     System.out.println ("exception caught while adding a shutdown hook:");
77                     e.printStackTrace (System.out);
78                 }
79             }
80 
81             return false;
82         }
83 
removeExitHook(final Runnable runnable)84         public synchronized boolean removeExitHook (final Runnable runnable)
85         {
86             if (runnable != null)
87             {
88                 final Thread exitThread = (Thread) m_exitThreadMap.get (runnable);  // TODO: use identity here
89 
90                 if (exitThread != null)
91                 {
92                     try
93                     {
94                         Runtime.getRuntime ().removeShutdownHook (exitThread);
95                         m_exitThreadMap.remove (runnable);
96 
97                         return true;
98                     }
99                     catch (Exception e)
100                     {
101                         System.out.println ("exception caught while removing a shutdown hook:");
102                         e.printStackTrace (System.out);
103                     }
104                 }
105             }
106 
107             return false;
108         }
109 
JRE13ExitHookManager()110         JRE13ExitHookManager ()
111         {
112             m_exitThreadMap = new HashMap ();
113         }
114 
115 
116         private final Map /* Runnable->Thread */ m_exitThreadMap;
117 
118     } // end of nested class
119 
120     private static ExitHookManager s_singleton;
121 
122 } // end of class
123 // ----------------------------------------------------------------------------
124