1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.util.thread;
20
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.List;
24 import java.util.concurrent.CopyOnWriteArrayList;
25
26 import org.eclipse.jetty.util.component.Destroyable;
27 import org.eclipse.jetty.util.component.LifeCycle;
28 import org.eclipse.jetty.util.log.Log;
29 import org.eclipse.jetty.util.log.Logger;
30
31
32
33
34
35
36
37
38
39 public class ShutdownThread extends Thread
40 {
41 private static final Logger LOG = Log.getLogger(ShutdownThread.class);
42 private static final ShutdownThread _thread = new ShutdownThread();
43
44 private boolean _hooked;
45 private final List<LifeCycle> _lifeCycles = new CopyOnWriteArrayList<LifeCycle>();
46
47
48
49
50
51
52
53 private ShutdownThread()
54 {
55 }
56
57
58 private synchronized void hook()
59 {
60 try
61 {
62 if (!_hooked)
63 Runtime.getRuntime().addShutdownHook(this);
64 _hooked=true;
65 }
66 catch(Exception e)
67 {
68 LOG.ignore(e);
69 LOG.info("shutdown already commenced");
70 }
71 }
72
73
74 private synchronized void unhook()
75 {
76 try
77 {
78 _hooked=false;
79 Runtime.getRuntime().removeShutdownHook(this);
80 }
81 catch(Exception e)
82 {
83 LOG.ignore(e);
84 LOG.debug("shutdown already commenced");
85 }
86 }
87
88
89
90
91
92
93
94 public static ShutdownThread getInstance()
95 {
96 return _thread;
97 }
98
99
100 public static synchronized void register(LifeCycle... lifeCycles)
101 {
102 _thread._lifeCycles.addAll(Arrays.asList(lifeCycles));
103 if (_thread._lifeCycles.size()>0)
104 _thread.hook();
105 }
106
107
108 public static synchronized void register(int index, LifeCycle... lifeCycles)
109 {
110 _thread._lifeCycles.addAll(index,Arrays.asList(lifeCycles));
111 if (_thread._lifeCycles.size()>0)
112 _thread.hook();
113 }
114
115
116 public static synchronized void deregister(LifeCycle lifeCycle)
117 {
118 _thread._lifeCycles.remove(lifeCycle);
119 if (_thread._lifeCycles.size()==0)
120 _thread.unhook();
121 }
122
123
124 @Override
125 public void run()
126 {
127 for (LifeCycle lifeCycle : _thread._lifeCycles)
128 {
129 try
130 {
131 if (lifeCycle.isStarted())
132 {
133 lifeCycle.stop();
134 LOG.debug("Stopped {}",lifeCycle);
135 }
136
137 if (lifeCycle instanceof Destroyable)
138 {
139 ((Destroyable)lifeCycle).destroy();
140 LOG.debug("Destroyed {}",lifeCycle);
141 }
142 }
143 catch (Exception ex)
144 {
145 LOG.debug(ex);
146 }
147 }
148 }
149 }