1 // ========================================================================
2 // Copyright (c) 2009-2009 Mort Bay Consulting Pty. Ltd.
3 // ------------------------------------------------------------------------
4 // All rights reserved. This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v1.0
6 // and Apache License v2.0 which accompanies this distribution.
7 // The Eclipse Public License is available at
8 // http://www.eclipse.org/legal/epl-v10.html
9 // The Apache License v2.0 is available at
10 // http://www.opensource.org/licenses/apache2.0.php
11 // You may elect to redistribute this code under either of these licenses.
12 // ========================================================================
13
14 package org.eclipse.jetty.util.thread;
15
16 import java.io.ObjectStreamException;
17 import java.util.ArrayList;
18 import java.util.Arrays;
19 import java.util.List;
20 import java.util.concurrent.CopyOnWriteArrayList;
21
22 import org.eclipse.jetty.util.component.AbstractLifeCycle;
23 import org.eclipse.jetty.util.component.LifeCycle;
24 import org.eclipse.jetty.util.log.Log;
25
26
27 /* ------------------------------------------------------------ */
28 /**
29 * ShutdownThread is a shutdown hook thread implemented as
30 * singleton that maintains a list of lifecycle instances
31 * that are registered with it and provides ability to stop
32 * these lifecycles upon shutdown of the Java Virtual Machine
33 */
34 public class ShutdownThread extends Thread
35 {
36 private static final ShutdownThread _thread = new ShutdownThread();
37
38 private final List<LifeCycle> _lifeCycles = new CopyOnWriteArrayList<LifeCycle>();
39
40 /* ------------------------------------------------------------ */
41 /**
42 * Default constructor for the singleton
43 *
44 * Registers the instance as shutdown hook with the Java Runtime
45 */
46 private ShutdownThread()
47 {
48 try
49 {
50 Runtime.getRuntime().addShutdownHook(this);
51 }
52 catch(Exception e)
53 {
54 Log.ignore(e);
55 Log.info("shutdown already commenced");
56 }
57 }
58
59 /* ------------------------------------------------------------ */
60 /**
61 * Returns the instance of the singleton
62 *
63 * @return the singleton instance of the {@link ShutdownThread}
64 */
65 public static ShutdownThread getInstance()
66 {
67 return _thread;
68 }
69
70 /* ------------------------------------------------------------ */
71 public static synchronized void register(LifeCycle... lifeCycles)
72 {
73 _thread._lifeCycles.addAll(Arrays.asList(lifeCycles));
74 }
75
76 /* ------------------------------------------------------------ */
77 public static synchronized void register(int index, LifeCycle... lifeCycles)
78 {
79 _thread._lifeCycles.addAll(index,Arrays.asList(lifeCycles));
80 }
81
82 /* ------------------------------------------------------------ */
83 public static synchronized void deregister(LifeCycle lifeCycle)
84 {
85 _thread._lifeCycles.remove(lifeCycle);
86 }
87
88 /* ------------------------------------------------------------ */
89 public void run()
90 {
91 for (LifeCycle lifeCycle : _thread._lifeCycles)
92 {
93 try
94 {
95 lifeCycle.stop();
96 Log.debug("Stopped " + lifeCycle);
97 }
98 catch (Exception ex)
99 {
100 Log.debug(ex);
101 }
102 }
103 }
104
105 /* ------------------------------------------------------------ */
106 protected Object readResolve()
107 throws ObjectStreamException
108 {
109 return _thread;
110 }
111 }