50 new StringBuffer("TimerQueue.sharedInstanceKey"); |
51 new StringBuffer("TimerQueue.sharedInstanceKey"); |
51 private static final Object expiredTimersKey = |
52 private static final Object expiredTimersKey = |
52 new StringBuffer("TimerQueue.expiredTimersKey"); |
53 new StringBuffer("TimerQueue.expiredTimersKey"); |
53 |
54 |
54 private final DelayQueue<DelayedTimer> queue; |
55 private final DelayQueue<DelayedTimer> queue; |
55 volatile boolean running; |
56 private volatile boolean running; |
|
57 private final Lock runningLock; |
56 |
58 |
57 /* Lock object used in place of class object for synchronization. |
59 /* Lock object used in place of class object for synchronization. |
58 * (4187686) |
60 * (4187686) |
59 */ |
61 */ |
60 private static final Object classLock = new Object(); |
62 private static final Object classLock = new Object(); |
85 return sharedInst; |
88 return sharedInst; |
86 } |
89 } |
87 } |
90 } |
88 |
91 |
89 |
92 |
90 synchronized void start() { |
93 void startIfNeeded() { |
91 if (running) { |
94 if (! running) { |
92 throw new RuntimeException("Can't start a TimerQueue " + |
95 runningLock.lock(); |
93 "that is already running"); |
96 try { |
94 } |
97 final ThreadGroup threadGroup = |
95 else { |
98 AppContext.getAppContext().getThreadGroup(); |
96 final ThreadGroup threadGroup = |
99 java.security.AccessController.doPrivileged( |
97 AppContext.getAppContext().getThreadGroup(); |
100 new java.security.PrivilegedAction() { |
98 java.security.AccessController.doPrivileged( |
101 public Object run() { |
99 new java.security.PrivilegedAction() { |
102 Thread timerThread = new Thread(threadGroup, TimerQueue.this, |
100 public Object run() { |
103 "TimerQueue"); |
101 Thread timerThread = new Thread(threadGroup, TimerQueue.this, |
104 timerThread.setDaemon(true); |
102 "TimerQueue"); |
105 timerThread.setPriority(Thread.NORM_PRIORITY); |
103 timerThread.setDaemon(true); |
106 timerThread.start(); |
104 timerThread.setPriority(Thread.NORM_PRIORITY); |
107 return null; |
105 timerThread.start(); |
108 } |
106 return null; |
109 }); |
107 } |
110 running = true; |
108 }); |
111 } finally { |
109 running = true; |
112 runningLock.unlock(); |
110 } |
113 } |
111 } |
114 } |
112 |
115 } |
113 synchronized void stop() { |
|
114 running = false; |
|
115 } |
|
116 |
116 |
117 void addTimer(Timer timer, long delayMillis) { |
117 void addTimer(Timer timer, long delayMillis) { |
118 timer.getLock().lock(); |
118 timer.getLock().lock(); |
119 try { |
119 try { |
120 // If the Timer is already in the queue, then ignore the add. |
120 // If the Timer is already in the queue, then ignore the add. |
193 } catch (InterruptedException ignore) { |
194 } catch (InterruptedException ignore) { |
194 } |
195 } |
195 } |
196 } |
196 } |
197 } |
197 catch (ThreadDeath td) { |
198 catch (ThreadDeath td) { |
198 synchronized (this) { |
199 // Mark all the timers we contain as not being queued. |
199 running = false; |
200 for (DelayedTimer delayedTimer : queue) { |
200 // Mark all the timers we contain as not being queued. |
201 delayedTimer.getTimer().cancelEvent(); |
201 for (DelayedTimer delayedTimer : queue) { |
202 } |
202 delayedTimer.getTimer().cancelEvent(); |
203 throw td; |
203 } |
204 } finally { |
204 throw td; |
205 running = false; |
205 } |
206 runningLock.unlock(); |
206 } |
207 } |
207 } |
208 } |
208 |
209 |
209 |
210 |
210 public String toString() { |
211 public String toString() { |