зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1062377 - Rewrite GeckoBackgroundThread to not wait for thread start if possible; r=rnewman
When GeckoBackgroundThread is first used, it starts a new thread and waits for a Handler. This can delay startup. Instead, we can just save the Runnable and run it when the thread is starting.
This commit is contained in:
Родитель
12d7d71d8f
Коммит
18d2c2ded2
|
@ -12,44 +12,65 @@ import java.util.concurrent.SynchronousQueue;
|
||||||
final class GeckoBackgroundThread extends Thread {
|
final class GeckoBackgroundThread extends Thread {
|
||||||
private static final String LOOPER_NAME = "GeckoBackgroundThread";
|
private static final String LOOPER_NAME = "GeckoBackgroundThread";
|
||||||
|
|
||||||
// Guarded by 'this'.
|
// Guarded by 'GeckoBackgroundThread.class'.
|
||||||
private static Handler sHandler;
|
private static Handler handler;
|
||||||
private SynchronousQueue<Handler> mHandlerQueue = new SynchronousQueue<Handler>();
|
private static Thread thread;
|
||||||
|
|
||||||
|
// The initial Runnable to run on the new thread. Its purpose
|
||||||
|
// is to avoid us having to wait for the new thread to start.
|
||||||
|
private Runnable initialRunnable;
|
||||||
|
|
||||||
// Singleton, so private constructor.
|
// Singleton, so private constructor.
|
||||||
private GeckoBackgroundThread() {
|
private GeckoBackgroundThread(final Runnable initialRunnable) {
|
||||||
super();
|
this.initialRunnable = initialRunnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
setName(LOOPER_NAME);
|
setName(LOOPER_NAME);
|
||||||
Looper.prepare();
|
Looper.prepare();
|
||||||
try {
|
|
||||||
mHandlerQueue.put(new Handler());
|
synchronized (GeckoBackgroundThread.class) {
|
||||||
} catch (InterruptedException ie) {}
|
handler = new Handler();
|
||||||
|
GeckoBackgroundThread.class.notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initialRunnable != null) {
|
||||||
|
initialRunnable.run();
|
||||||
|
initialRunnable = null;
|
||||||
|
}
|
||||||
|
|
||||||
Looper.loop();
|
Looper.loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a Handler for a looper thread, or create one if it doesn't yet exist.
|
private static void startThread(final Runnable initialRunnable) {
|
||||||
/*package*/ static synchronized Handler getHandler() {
|
thread = new GeckoBackgroundThread(initialRunnable);
|
||||||
if (sHandler == null) {
|
ThreadUtils.setBackgroundThread(thread);
|
||||||
GeckoBackgroundThread lt = new GeckoBackgroundThread();
|
|
||||||
ThreadUtils.setBackgroundThread(lt);
|
thread.setDaemon(true);
|
||||||
lt.start();
|
thread.start();
|
||||||
try {
|
|
||||||
sHandler = lt.mHandlerQueue.take();
|
|
||||||
} catch (InterruptedException ie) {}
|
|
||||||
}
|
|
||||||
return sHandler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ static void post(Runnable runnable) {
|
// Get a Handler for a looper thread, or create one if it doesn't yet exist.
|
||||||
Handler handler = getHandler();
|
/*package*/ static synchronized Handler getHandler() {
|
||||||
if (handler == null) {
|
if (thread == null) {
|
||||||
throw new IllegalStateException("No handler! Must have been interrupted. Not posting.");
|
startThread(null);
|
||||||
}
|
}
|
||||||
handler.post(runnable);
|
|
||||||
|
while (handler == null) {
|
||||||
|
try {
|
||||||
|
GeckoBackgroundThread.class.wait();
|
||||||
|
} catch (final InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*package*/ static synchronized void post(final Runnable runnable) {
|
||||||
|
if (thread == null) {
|
||||||
|
startThread(runnable);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
getHandler().post(runnable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче