annotate src/ch/ethz/ssh2/util/TimeoutService.java @ 273:91a31873c42a ganymed

start conversion from trilead to ganymed
author Carl Byington <carl@five-ten-sg.com>
date Fri, 18 Jul 2014 11:21:46 -0700
parents
children 071eccdff8ea
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
1 /*
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
2 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
3 * Please refer to the LICENSE.txt for licensing details.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
4 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
5
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
6 package ch.ethz.ssh2.util;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
7
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
8 import java.io.PrintWriter;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
9 import java.io.StringWriter;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
10 import java.util.Collections;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
11 import java.util.Comparator;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
12 import java.util.LinkedList;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
13
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
14 import ch.ethz.ssh2.log.Logger;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
15
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
16 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
17 * TimeoutService (beta). Here you can register a timeout.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
18 * <p>
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
19 * Implemented having large scale programs in mind: if you open many concurrent SSH connections
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
20 * that rely on timeouts, then there will be only one timeout thread. Once all timeouts
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
21 * have expired/are cancelled, the thread will (sooner or later) exit.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
22 * Only after new timeouts arrive a new thread (singleton) will be instantiated.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
23 *
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
24 * @author Christian Plattner
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
25 * @version $Id: TimeoutService.java 89 2014-04-07 14:36:24Z dkocher@sudo.ch $
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
26 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
27 public class TimeoutService
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
28 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
29 private static final Logger log = Logger.getLogger(TimeoutService.class);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
30
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
31 public static class TimeoutToken
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
32 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
33 private long runTime;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
34 private Runnable handler;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
35
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
36 private TimeoutToken(long runTime, Runnable handler)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
37 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
38 this.runTime = runTime;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
39 this.handler = handler;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
40 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
41 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
42
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
43 private static class TimeoutThread extends Thread
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
44 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
45 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
46 public void run()
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
47 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
48 synchronized (todolist)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
49 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
50 while (true)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
51 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
52 if (todolist.size() == 0)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
53 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
54 timeoutThread = null;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
55 return;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
56 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
57
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
58 long now = System.currentTimeMillis();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
59
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
60 TimeoutToken tt = todolist.getFirst();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
61
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
62 if (tt.runTime > now)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
63 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
64 /* Not ready yet, sleep a little bit */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
65
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
66 try
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
67 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
68 todolist.wait(tt.runTime - now);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
69 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
70 catch (InterruptedException ignored)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
71 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
72 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
73
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
74 /* We cannot simply go on, since it could be that the token
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
75 * was removed (cancelled) or another one has been inserted in
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
76 * the meantime.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
77 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
78
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
79 continue;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
80 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
81
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
82 todolist.removeFirst();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
83
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
84 try
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
85 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
86 tt.handler.run();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
87 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
88 catch (Exception e)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
89 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
90 StringWriter sw = new StringWriter();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
91 e.printStackTrace(new PrintWriter(sw));
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
92 log.warning("Exeception in Timeout handler:" + e.getMessage() + "(" + sw.toString() + ")");
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
93 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
94 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
95 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
96 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
97 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
98
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
99 /* The list object is also used for locking purposes */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
100 private static final LinkedList<TimeoutToken> todolist = new LinkedList<TimeoutService.TimeoutToken>();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
101
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
102 private static Thread timeoutThread = null;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
103
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
104 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
105 * It is assumed that the passed handler will not execute for a long time.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
106 *
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
107 * @param runTime
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
108 * @param handler
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
109 * @return a TimeoutToken that can be used to cancel the timeout.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
110 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
111 public static TimeoutToken addTimeoutHandler(long runTime, Runnable handler)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
112 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
113 TimeoutToken token = new TimeoutToken(runTime, handler);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
114
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
115 synchronized (todolist)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
116 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
117 todolist.add(token);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
118
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
119 Collections.sort(todolist, new Comparator<TimeoutToken>()
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
120 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
121 public int compare(TimeoutToken o1, TimeoutToken o2)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
122 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
123 if (o1.runTime > o2.runTime)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
124 return 1;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
125 if (o1.runTime == o2.runTime)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
126 return 0;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
127 return -1;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
128 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
129 });
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
130
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
131 if (timeoutThread != null)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
132 timeoutThread.interrupt();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
133 else
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
134 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
135 timeoutThread = new TimeoutThread();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
136 timeoutThread.setDaemon(true);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
137 timeoutThread.start();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
138 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
139 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
140
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
141 return token;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
142 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
143
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
144 public static void cancelTimeoutHandler(TimeoutToken token)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
145 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
146 synchronized (todolist)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
147 {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
148 todolist.remove(token);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
149
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
150 if (timeoutThread != null)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
151 timeoutThread.interrupt();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
152 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
153 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
154
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
155 }