diff -r 1f0034e370aa -r 71ad690e91f5 javauis/lcdui_qt/src/javax/microedition/lcdui/EventDispatcher.java --- a/javauis/lcdui_qt/src/javax/microedition/lcdui/EventDispatcher.java Fri Sep 17 16:44:34 2010 +0300 +++ b/javauis/lcdui_qt/src/javax/microedition/lcdui/EventDispatcher.java Mon Oct 04 11:29:25 2010 +0300 @@ -32,8 +32,10 @@ private static EventQueue eventQueue; private static Thread dispatcherThread; private static boolean terminated; + private static boolean terminateCalled; private static Object wakeLock; private static Object callbackLock; + private static Object terminationLock; private static boolean pendingWake; private static Runnable terminatedNotification; private final static String logName = "LCDUI event dispatcher: "; @@ -177,18 +179,22 @@ } finally { - if(noException) - { - Logger.info(logName + "Dispatcher thread exiting normally"); - } - else + synchronized(terminationLock) { - Logger.error(logName + "Dispatcher thread exiting abnormally"); - } - if(terminatedNotification != null) - { - terminatedNotification.run(); - terminatedNotification = null; + terminated = true; + if(noException) + { + Logger.info(logName + "Dispatcher thread exiting normally"); + } + else + { + Logger.error(logName + "Dispatcher thread exiting abnormally"); + } + if(terminatedNotification != null) + { + terminatedNotification.run(); + terminatedNotification = null; + } } } } @@ -198,6 +204,7 @@ { wakeLock = new Object(); callbackLock = new Object(); + terminationLock = new Object(); eventQueue = new EventQueue(); dispatcherThread = new Thread(new EventLoop(), this.toString()); dispatcherThread.start(); @@ -264,11 +271,32 @@ */ synchronized void terminate(Runnable runnable) { - synchronized(wakeLock) + synchronized(terminationLock) { - wake(); - terminatedNotification = runnable; - terminated = true; + // Only the first call does something + if(!terminateCalled) + { + terminateCalled = true; + if(terminated) + { + // Already terminated. Dispatcher thread is not available + // anymore for the asynchronous notification callback. Do + // the callback in the current thread. + if(runnable != null) + { + runnable.run(); + } + } + else + { + synchronized(wakeLock) + { + wake(); + terminatedNotification = runnable; + terminated = true; + } + } + } } }