diff options
author | Upstream <upstream-import@none> | 1970-01-12 13:46:40 +0000 |
---|---|---|
committer | Upstream <upstream-import@none> | 1970-01-12 13:46:40 +0000 |
commit | a921fd048da6858dc24d4370e3bba15fc9cc69ca (patch) | |
tree | 05caf4ec8cdf2edff2fcabe72522041710f2b756 /core/java13 | |
download | emma-a921fd048da6858dc24d4370e3bba15fc9cc69ca.tar.gz |
external/emma 2.0.5312upstream/2.0.5312
Diffstat (limited to 'core/java13')
-rw-r--r-- | core/java13/com/vladium/util/exit/ExitHookManager.java | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/core/java13/com/vladium/util/exit/ExitHookManager.java b/core/java13/com/vladium/util/exit/ExitHookManager.java new file mode 100644 index 0000000..c119268 --- /dev/null +++ b/core/java13/com/vladium/util/exit/ExitHookManager.java @@ -0,0 +1,252 @@ +/* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved. + * + * This program and the accompanying materials are made available under + * the terms of the Common Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/cpl-v10.html + * + * $Id: ExitHookManager.java,v 1.1.1.1 2004/05/09 16:57:58 vlad_r Exp $ + */ +package com.vladium.util.exit; + +import java.util.HashMap; +import java.util.Map; + +import sun.misc.Signal; +import sun.misc.SignalHandler; + +import com.vladium.util.IJREVersion; +import com.vladium.util.Property; +import com.vladium.emma.IAppConstants; + +// ---------------------------------------------------------------------------- +/** + * @author Vlad Roubtsov, (C) 2003 + */ +public +abstract class ExitHookManager implements IJREVersion +{ + // public: ................................................................ + + // TOTO: handle thread groups as well? + + public abstract boolean addExitHook (Runnable runnable); + public abstract boolean removeExitHook (Runnable runnable); + + public static synchronized ExitHookManager getSingleton () + { + if (s_singleton == null) + { + if (JRE_1_3_PLUS) + { + s_singleton = new JRE13ExitHookManager (); + } + else if (JRE_SUN_SIGNAL_COMPATIBLE) + { + s_singleton = new SunJREExitHookManager (); + } + else + { + throw new UnsupportedOperationException ("no shutdown hook manager available [JVM: " + Property.getSystemFingerprint () + "]"); + } + } + + return s_singleton; + } + + // protected: ............................................................. + + + protected ExitHookManager () {} + + // package: ............................................................... + + // private: ............................................................... + + + private static final class JRE13ExitHookManager extends ExitHookManager + { + public synchronized boolean addExitHook (final Runnable runnable) + { + if ((runnable != null) && ! m_exitThreadMap.containsKey (runnable)) + { + final Thread exitThread = new Thread (runnable, IAppConstants.APP_NAME + " shutdown handler thread"); + + try + { + Runtime.getRuntime ().addShutdownHook (exitThread); + m_exitThreadMap.put (runnable, exitThread); // TODO: use identity here + + return true; + } + catch (Exception e) + { + System.out.println ("exception caught while adding a shutdown hook:"); + e.printStackTrace (System.out); + } + } + + return false; + } + + public synchronized boolean removeExitHook (final Runnable runnable) + { + if (runnable != null) + { + final Thread exitThread = (Thread) m_exitThreadMap.get (runnable); // TODO: use identity here + + if (exitThread != null) + { + try + { + Runtime.getRuntime ().removeShutdownHook (exitThread); + m_exitThreadMap.remove (runnable); + + return true; + } + catch (Exception e) + { + System.out.println ("exception caught while removing a shutdown hook:"); + e.printStackTrace (System.out); + } + } + } + + return false; + } + + JRE13ExitHookManager () + { + m_exitThreadMap = new HashMap (); + } + + + private final Map /* Runnable->Thread */ m_exitThreadMap; + + } // end of nested class + + + private static final class SunJREExitHookManager extends ExitHookManager + { + public synchronized boolean addExitHook (final Runnable runnable) + { + if ((runnable != null) && ! m_signalHandlerMap.containsKey (runnable)) + { + final INTSignalHandler handler = new INTSignalHandler (runnable); + + try + { + handler.register (); + m_signalHandlerMap.put (runnable, handler); // TODO: use identity here + + return true; + } + catch (Throwable t) + { + System.out.println ("exception caught while adding a shutdown hook:"); + t.printStackTrace (System.out); + } + } + + return false; + } + + public synchronized boolean removeExitHook (final Runnable runnable) + { + if (runnable != null) + { + final INTSignalHandler handler = (INTSignalHandler) m_signalHandlerMap.get (runnable); // TODO: use identity here + if (handler != null) + { + try + { + handler.unregister (); + m_signalHandlerMap.remove (runnable); + + return true; + } + catch (Exception e) + { + System.out.println ("exception caught while removing a shutdown hook:"); + e.printStackTrace (System.out); + } + } + } + + return false; + } + + SunJREExitHookManager () + { + m_signalHandlerMap = new HashMap (); + } + + + private final Map /* Runnable->INTSignalHandler */ m_signalHandlerMap; + + } // end of nested class + + + private static final class INTSignalHandler implements SignalHandler + { + public synchronized void handle (final Signal signal) + { + if (m_runnable != null) + { + try + { + m_runnable.run (); + } + catch (Throwable ignore) {} + } + m_runnable = null; + + if ((m_previous != null) && (m_previous != SIG_DFL) && (m_previous != SIG_IGN)) + { + try + { + // this does not work: + //Signal.handle (signal, m_previous); + //Signal.raise (signal); + + m_previous.handle (signal); + } + catch (Throwable ignore) {} + } + else + { + System.exit (0); + } + } + + INTSignalHandler (final Runnable runnable) + { + m_runnable = runnable; + } + + synchronized void register () + { + m_previous = Signal.handle (new Signal ("INT"), this); + } + + synchronized void unregister () + { +// if (m_previous != null) +// { +// Signal.handle (new Signal ("INT"), m_previous); +// m_previous = null; +// } + + m_runnable = null; + } + + + private Runnable m_runnable; + private SignalHandler m_previous; + + } // end of nested class + + + private static ExitHookManager s_singleton; + +} // end of class +// ----------------------------------------------------------------------------
\ No newline at end of file |