01: /*
02: * This is free software, licensed under the Gnu Public License (GPL)
03: * get a copy from <http://www.gnu.org/licenses/gpl.html>
04: * $Id: SigIntHandler.java,v 1.9 2005/12/14 10:53:03 hzeller Exp $
05: * author: Henner Zeller <H.Zeller@acm.org>
06: */
07: package henplus;
08:
09: import java.util.Stack;
10: import java.util.ListIterator;
11: import sun.misc.Signal;
12: import sun.misc.SignalHandler;
13:
14: /**
15: * Signal handler, that reacts on CTRL-C.
16: */
17: public class SigIntHandler implements SignalHandler, InterruptHandler {
18: private static InterruptHandler DUMMY_HANDLER = new InterruptHandler() {
19: public void popInterruptable() {
20: }
21:
22: public void pushInterruptable(Interruptable t) {
23: }
24:
25: public void reset() {
26: }
27: };
28:
29: private boolean once;
30: private static SigIntHandler instance = null;
31: private final Stack toInterruptStack;
32:
33: public static void install() {
34: Signal interruptSignal = new Signal("INT"); // Interrupt: Ctrl-C
35: instance = new SigIntHandler();
36: // don't care about the original handler.
37: Signal.handle(interruptSignal, instance);
38: }
39:
40: public static InterruptHandler getInstance() {
41: if (instance == null)
42: return DUMMY_HANDLER;
43: return instance;
44: }
45:
46: public SigIntHandler() {
47: once = false;
48: toInterruptStack = new Stack();
49: }
50:
51: public void pushInterruptable(Interruptable t) {
52: toInterruptStack.push(t);
53: }
54:
55: public void popInterruptable() {
56: once = false;
57: toInterruptStack.pop();
58: }
59:
60: public void reset() {
61: once = false;
62: toInterruptStack.clear();
63: }
64:
65: public void handle(Signal sig) {
66: if (once) {
67: // got the interrupt more than once. May happen if you press
68: // Ctrl-C multiple times .. or with broken thread lib on Linux.
69: return;
70: }
71:
72: once = true;
73: if (!toInterruptStack.empty()) {
74: ListIterator it = toInterruptStack
75: .listIterator(toInterruptStack.size());
76: while (it.hasPrevious()) {
77: Interruptable toInterrupt = (Interruptable) it
78: .previous();
79: toInterrupt.interrupt();
80: }
81: } else {
82: System.err.println("[Ctrl-C ; interrupted]");
83: System.exit(1);
84: }
85: }
86: }
87:
88: /*
89: * Local variables:
90: * c-basic-offset: 4
91: * compile-command: "ant -emacs -find build.xml"
92: * End:
93: */
|