1 22 package org.jboss.util.timeout; 23 24 import org.jboss.util.NestedRuntimeException; 25 import org.jboss.util.ThrowableHandler; 26 import org.jboss.util.threadpool.BasicThreadPool; 27 import org.jboss.util.threadpool.BlockingMode; 28 import org.jboss.util.threadpool.ThreadPool; 29 30 import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean; 31 32 41 public class TimeoutFactory 42 { 43 44 private static final String priorityQueueProperty = TimeoutPriorityQueue.class.getName(); 45 46 47 private static final String priorityQueueName = TimeoutPriorityQueueImpl.class.getName(); 48 49 50 private static TimeoutFactory singleton; 51 52 53 private static int timeoutFactoriesCount = 0; 54 55 56 private static Class priorityQueueClass; 57 58 59 private static BasicThreadPool DEFAULT_TP = new BasicThreadPool("Timeouts"); 60 static 61 { 62 DEFAULT_TP.setBlockingMode(BlockingMode.RUN); 63 64 String priorityQueueClassName = priorityQueueName; 65 ClassLoader cl = TimeoutFactory.class.getClassLoader(); 66 try 67 { 68 priorityQueueClassName = System.getProperty(priorityQueueProperty, priorityQueueName); 69 cl = Thread.currentThread().getContextClassLoader(); 70 } 71 catch (Exception ignored) 72 { 73 } 74 75 try 76 { 77 priorityQueueClass = cl.loadClass(priorityQueueClassName); 78 } 79 catch (Exception e) 80 { 81 throw new NestedRuntimeException(e.toString(), e); 82 } 83 } 84 85 86 private SynchronizedBoolean cancelled = new SynchronizedBoolean(false); 87 88 90 private Thread workerThread; 91 92 93 private ThreadPool threadPool; 94 95 96 private TimeoutPriorityQueue queue; 97 98 99 public synchronized static TimeoutFactory getSingleton() 100 { 101 if (singleton == null) 102 { 103 singleton = new TimeoutFactory(DEFAULT_TP); 104 } 105 return singleton; 106 } 107 108 111 static public Timeout createTimeout(long time, TimeoutTarget target) 112 { 113 return getSingleton().schedule(time, target); 114 } 115 116 119 public TimeoutFactory(ThreadPool threadPool) 120 { 121 this.threadPool = threadPool; 122 try 123 { 124 queue = (TimeoutPriorityQueue) priorityQueueClass.newInstance(); 125 } 126 catch (Exception e) 127 { 128 throw new RuntimeException ("Cannot instantiate " + priorityQueueClass,e); 129 } 130 131 workerThread = new Thread ("TimeoutFactory-" + timeoutFactoriesCount++) 133 { 134 public void run() 135 { 136 doWork(); 137 } 138 }; 139 workerThread.setDaemon(true); 140 workerThread.start(); 141 } 142 143 146 public TimeoutFactory() 147 { 148 this(DEFAULT_TP); 149 } 150 151 157 public Timeout schedule(long time, TimeoutTarget target) 158 { 159 if (cancelled.get()) 160 throw new IllegalStateException ("TimeoutFactory has been cancelled"); 161 if (time < 0) 162 throw new IllegalArgumentException ("Negative time"); 163 if (target == null) 164 throw new IllegalArgumentException ("Null timeout target"); 165 166 return queue.offer(time, target); 167 } 168 169 175 public Timeout schedule(long time, Runnable run) 176 { 177 return schedule(time, new TimeoutTargetImpl(run)); 178 } 179 180 186 public void cancel() 187 { 188 191 if (cancelled.set(true) == false); 193 { 194 queue.cancel(); 196 } 197 } 198 199 203 public boolean isCancelled() 204 { 205 return cancelled.get(); 206 } 207 208 211 private void doWork() 212 { 213 while (cancelled.get() == false) 214 { 215 TimeoutExt work = queue.take(); 216 if (work != null) 218 { 219 TimeoutWorker worker = new TimeoutWorker(work); 221 try 222 { 223 threadPool.run(worker); 224 } 225 catch (Throwable t) 226 { 227 ThrowableHandler.add(ThrowableHandler.Type.ERROR, t); 229 } 230 synchronized (work) 231 { 232 work.done(); 233 } 234 } 235 } 236 237 queue.cancel(); 239 } 240 241 244 private static class TimeoutWorker implements Runnable 245 { 246 private TimeoutExt work; 247 248 253 TimeoutWorker(TimeoutExt work) 254 { 255 this.work = work; 256 } 257 258 261 public void run() 262 { 263 try 264 { 265 work.getTimeoutTarget().timedOut(work); 266 } 267 catch (Throwable t) 268 { 269 ThrowableHandler.add(ThrowableHandler.Type.ERROR, t); 271 } 272 synchronized (work) 273 { 274 work.done(); 275 } 276 } 277 } 278 279 282 private static class TimeoutTargetImpl implements TimeoutTarget 283 { 284 Runnable runnable; 285 286 TimeoutTargetImpl(Runnable runnable) 287 { 288 this.runnable = runnable; 289 } 290 291 public void timedOut(Timeout ignored) 292 { 293 runnable.run(); 294 } 295 } 296 } | Popular Tags |