mobile/android/base/util/ThreadUtils.java

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 package org.mozilla.gecko.util;
michael@0 7
michael@0 8 import java.util.Map;
michael@0 9
michael@0 10 import android.os.Handler;
michael@0 11 import android.os.MessageQueue;
michael@0 12 import android.util.Log;
michael@0 13
michael@0 14 public final class ThreadUtils {
michael@0 15 private static final String LOGTAG = "ThreadUtils";
michael@0 16
michael@0 17 /**
michael@0 18 * Controls the action taken when a method like
michael@0 19 * {@link ThreadUtils#assertOnUiThread(AssertBehavior)} detects a problem.
michael@0 20 */
michael@0 21 public static enum AssertBehavior {
michael@0 22 NONE,
michael@0 23 THROW,
michael@0 24 }
michael@0 25
michael@0 26 private static volatile Thread sUiThread;
michael@0 27 private static volatile Thread sBackgroundThread;
michael@0 28
michael@0 29 private static Handler sUiHandler;
michael@0 30
michael@0 31 // Referenced directly from GeckoAppShell in highly performance-sensitive code (The extra
michael@0 32 // function call of the getter was harming performance. (Bug 897123))
michael@0 33 // Once Bug 709230 is resolved we should reconsider this as ProGuard should be able to optimise
michael@0 34 // this out at compile time.
michael@0 35 public static Handler sGeckoHandler;
michael@0 36 public static MessageQueue sGeckoQueue;
michael@0 37 public static Thread sGeckoThread;
michael@0 38
michael@0 39 // Delayed Runnable that resets the Gecko thread priority.
michael@0 40 private static final Runnable sPriorityResetRunnable = new Runnable() {
michael@0 41 @Override
michael@0 42 public void run() {
michael@0 43 resetGeckoPriority();
michael@0 44 }
michael@0 45 };
michael@0 46
michael@0 47 private static boolean sIsGeckoPriorityReduced;
michael@0 48
michael@0 49 @SuppressWarnings("serial")
michael@0 50 public static class UiThreadBlockedException extends RuntimeException {
michael@0 51 public UiThreadBlockedException() {
michael@0 52 super();
michael@0 53 }
michael@0 54
michael@0 55 public UiThreadBlockedException(String msg) {
michael@0 56 super(msg);
michael@0 57 }
michael@0 58
michael@0 59 public UiThreadBlockedException(String msg, Throwable e) {
michael@0 60 super(msg, e);
michael@0 61 }
michael@0 62
michael@0 63 public UiThreadBlockedException(Throwable e) {
michael@0 64 super(e);
michael@0 65 }
michael@0 66 }
michael@0 67
michael@0 68 public static void dumpAllStackTraces() {
michael@0 69 Log.w(LOGTAG, "Dumping ALL the threads!");
michael@0 70 Map<Thread, StackTraceElement[]> allStacks = Thread.getAllStackTraces();
michael@0 71 for (Thread t : allStacks.keySet()) {
michael@0 72 Log.w(LOGTAG, t.toString());
michael@0 73 for (StackTraceElement ste : allStacks.get(t)) {
michael@0 74 Log.w(LOGTAG, ste.toString());
michael@0 75 }
michael@0 76 Log.w(LOGTAG, "----");
michael@0 77 }
michael@0 78 }
michael@0 79
michael@0 80 public static void setUiThread(Thread thread, Handler handler) {
michael@0 81 sUiThread = thread;
michael@0 82 sUiHandler = handler;
michael@0 83 }
michael@0 84
michael@0 85 public static void setBackgroundThread(Thread thread) {
michael@0 86 sBackgroundThread = thread;
michael@0 87 }
michael@0 88
michael@0 89 public static Thread getUiThread() {
michael@0 90 return sUiThread;
michael@0 91 }
michael@0 92
michael@0 93 public static Handler getUiHandler() {
michael@0 94 return sUiHandler;
michael@0 95 }
michael@0 96
michael@0 97 public static void postToUiThread(Runnable runnable) {
michael@0 98 sUiHandler.post(runnable);
michael@0 99 }
michael@0 100
michael@0 101 public static Thread getBackgroundThread() {
michael@0 102 return sBackgroundThread;
michael@0 103 }
michael@0 104
michael@0 105 public static Handler getBackgroundHandler() {
michael@0 106 return GeckoBackgroundThread.getHandler();
michael@0 107 }
michael@0 108
michael@0 109 public static void postToBackgroundThread(Runnable runnable) {
michael@0 110 GeckoBackgroundThread.post(runnable);
michael@0 111 }
michael@0 112
michael@0 113 public static void assertOnUiThread(final AssertBehavior assertBehavior) {
michael@0 114 assertOnThread(getUiThread(), assertBehavior);
michael@0 115 }
michael@0 116
michael@0 117 public static void assertOnUiThread() {
michael@0 118 assertOnThread(getUiThread(), AssertBehavior.THROW);
michael@0 119 }
michael@0 120
michael@0 121 public static void assertOnGeckoThread() {
michael@0 122 assertOnThread(sGeckoThread, AssertBehavior.THROW);
michael@0 123 }
michael@0 124
michael@0 125 public static void assertOnBackgroundThread() {
michael@0 126 assertOnThread(getBackgroundThread(), AssertBehavior.THROW);
michael@0 127 }
michael@0 128
michael@0 129 public static void assertOnThread(final Thread expectedThread) {
michael@0 130 assertOnThread(expectedThread, AssertBehavior.THROW);
michael@0 131 }
michael@0 132
michael@0 133 public static void assertOnThread(final Thread expectedThread, AssertBehavior behavior) {
michael@0 134 final Thread currentThread = Thread.currentThread();
michael@0 135 final long currentThreadId = currentThread.getId();
michael@0 136 final long expectedThreadId = expectedThread.getId();
michael@0 137
michael@0 138 if (currentThreadId == expectedThreadId) {
michael@0 139 return;
michael@0 140 }
michael@0 141
michael@0 142 final String message = "Expected thread " +
michael@0 143 expectedThreadId + " (\"" + expectedThread.getName() +
michael@0 144 "\"), but running on thread " +
michael@0 145 currentThreadId + " (\"" + currentThread.getName() + ")";
michael@0 146 final IllegalThreadStateException e = new IllegalThreadStateException(message);
michael@0 147
michael@0 148 switch (behavior) {
michael@0 149 case THROW:
michael@0 150 throw e;
michael@0 151 default:
michael@0 152 Log.e(LOGTAG, "Method called on wrong thread!", e);
michael@0 153 }
michael@0 154 }
michael@0 155
michael@0 156 public static boolean isOnUiThread() {
michael@0 157 return isOnThread(getUiThread());
michael@0 158 }
michael@0 159
michael@0 160 public static boolean isOnBackgroundThread() {
michael@0 161 if (sBackgroundThread == null) {
michael@0 162 return false;
michael@0 163 }
michael@0 164
michael@0 165 return isOnThread(sBackgroundThread);
michael@0 166 }
michael@0 167
michael@0 168 public static boolean isOnThread(Thread thread) {
michael@0 169 return (Thread.currentThread().getId() == thread.getId());
michael@0 170 }
michael@0 171
michael@0 172 /**
michael@0 173 * Reduces the priority of the Gecko thread, allowing other operations
michael@0 174 * (such as those related to the UI and database) to take precedence.
michael@0 175 *
michael@0 176 * Note that there are no guards in place to prevent multiple calls
michael@0 177 * to this method from conflicting with each other.
michael@0 178 *
michael@0 179 * @param timeout Timeout in ms after which the priority will be reset
michael@0 180 */
michael@0 181 public static void reduceGeckoPriority(long timeout) {
michael@0 182 if (!sIsGeckoPriorityReduced) {
michael@0 183 sIsGeckoPriorityReduced = true;
michael@0 184 sGeckoThread.setPriority(Thread.MIN_PRIORITY);
michael@0 185 getUiHandler().postDelayed(sPriorityResetRunnable, timeout);
michael@0 186 }
michael@0 187 }
michael@0 188
michael@0 189 /**
michael@0 190 * Resets the priority of a thread whose priority has been reduced
michael@0 191 * by reduceGeckoPriority.
michael@0 192 */
michael@0 193 public static void resetGeckoPriority() {
michael@0 194 if (sIsGeckoPriorityReduced) {
michael@0 195 sIsGeckoPriorityReduced = false;
michael@0 196 sGeckoThread.setPriority(Thread.NORM_PRIORITY);
michael@0 197 getUiHandler().removeCallbacks(sPriorityResetRunnable);
michael@0 198 }
michael@0 199 }
michael@0 200 }

mercurial