equal
deleted
inserted
replaced
30 |
30 |
31 private static EventDispatcher singleton; |
31 private static EventDispatcher singleton; |
32 private static EventQueue eventQueue; |
32 private static EventQueue eventQueue; |
33 private static Thread dispatcherThread; |
33 private static Thread dispatcherThread; |
34 private static boolean terminated; |
34 private static boolean terminated; |
|
35 private static boolean terminateCalled; |
35 private static Object wakeLock; |
36 private static Object wakeLock; |
36 private static Object callbackLock; |
37 private static Object callbackLock; |
|
38 private static Object terminationLock; |
37 private static boolean pendingWake; |
39 private static boolean pendingWake; |
38 private static Runnable terminatedNotification; |
40 private static Runnable terminatedNotification; |
39 private final static String logName = "LCDUI event dispatcher: "; |
41 private final static String logName = "LCDUI event dispatcher: "; |
40 |
42 |
41 /* |
43 /* |
175 waitForWake(); |
177 waitForWake(); |
176 } |
178 } |
177 } |
179 } |
178 finally |
180 finally |
179 { |
181 { |
180 if(noException) |
182 synchronized(terminationLock) |
181 { |
183 { |
182 Logger.info(logName + "Dispatcher thread exiting normally"); |
184 terminated = true; |
183 } |
185 if(noException) |
184 else |
186 { |
185 { |
187 Logger.info(logName + "Dispatcher thread exiting normally"); |
186 Logger.error(logName + "Dispatcher thread exiting abnormally"); |
188 } |
187 } |
189 else |
188 if(terminatedNotification != null) |
190 { |
189 { |
191 Logger.error(logName + "Dispatcher thread exiting abnormally"); |
190 terminatedNotification.run(); |
192 } |
191 terminatedNotification = null; |
193 if(terminatedNotification != null) |
|
194 { |
|
195 terminatedNotification.run(); |
|
196 terminatedNotification = null; |
|
197 } |
192 } |
198 } |
193 } |
199 } |
194 } |
200 } |
195 } |
201 } |
196 |
202 |
197 private EventDispatcher() |
203 private EventDispatcher() |
198 { |
204 { |
199 wakeLock = new Object(); |
205 wakeLock = new Object(); |
200 callbackLock = new Object(); |
206 callbackLock = new Object(); |
|
207 terminationLock = new Object(); |
201 eventQueue = new EventQueue(); |
208 eventQueue = new EventQueue(); |
202 dispatcherThread = new Thread(new EventLoop(), this.toString()); |
209 dispatcherThread = new Thread(new EventLoop(), this.toString()); |
203 dispatcherThread.start(); |
210 dispatcherThread.start(); |
204 } |
211 } |
205 |
212 |
262 * @param runnable Called when dispatcher is out of the final callback and |
269 * @param runnable Called when dispatcher is out of the final callback and |
263 * is going to die. |
270 * is going to die. |
264 */ |
271 */ |
265 synchronized void terminate(Runnable runnable) |
272 synchronized void terminate(Runnable runnable) |
266 { |
273 { |
267 synchronized(wakeLock) |
274 synchronized(terminationLock) |
268 { |
275 { |
269 wake(); |
276 // Only the first call does something |
270 terminatedNotification = runnable; |
277 if(!terminateCalled) |
271 terminated = true; |
278 { |
|
279 terminateCalled = true; |
|
280 if(terminated) |
|
281 { |
|
282 // Already terminated. Dispatcher thread is not available |
|
283 // anymore for the asynchronous notification callback. Do |
|
284 // the callback in the current thread. |
|
285 if(runnable != null) |
|
286 { |
|
287 runnable.run(); |
|
288 } |
|
289 } |
|
290 else |
|
291 { |
|
292 synchronized(wakeLock) |
|
293 { |
|
294 wake(); |
|
295 terminatedNotification = runnable; |
|
296 terminated = true; |
|
297 } |
|
298 } |
|
299 } |
272 } |
300 } |
273 } |
301 } |
274 |
302 |
275 /* |
303 /* |
276 * Canvas.serviceRepaints support is implemented in EventDispatcher so that |
304 * Canvas.serviceRepaints support is implemented in EventDispatcher so that |