Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1787)

Side by Side Diff: webrtc/base/java/src/org/webrtc/ThreadUtils.java

Issue 2877023002: Move webrtc/{base => rtc_base} (Closed)
Patch Set: update presubmit.py and DEPS include rules Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/base/java/src/org/webrtc/Size.java ('k') | webrtc/base/json.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 package org.webrtc;
12
13 import android.os.Handler;
14 import android.os.Looper;
15 import android.os.SystemClock;
16 import java.util.concurrent.Callable;
17 import java.util.concurrent.CountDownLatch;
18 import java.util.concurrent.TimeUnit;
19
20 public class ThreadUtils {
21 /**
22 * Utility class to be used for checking that a method is called on the correc t thread.
23 */
24 public static class ThreadChecker {
25 private Thread thread = Thread.currentThread();
26
27 public void checkIsOnValidThread() {
28 if (thread == null) {
29 thread = Thread.currentThread();
30 }
31 if (Thread.currentThread() != thread) {
32 throw new IllegalStateException("Wrong thread");
33 }
34 }
35
36 public void detachThread() {
37 thread = null;
38 }
39 }
40
41 /**
42 * Throws exception if called from other than main thread.
43 */
44 public static void checkIsOnMainThread() {
45 if (Thread.currentThread() != Looper.getMainLooper().getThread()) {
46 throw new IllegalStateException("Not on main thread!");
47 }
48 }
49
50 /**
51 * Utility interface to be used with executeUninterruptibly() to wait for bloc king operations
52 * to complete without getting interrupted..
53 */
54 public interface BlockingOperation { void run() throws InterruptedException; }
55
56 /**
57 * Utility method to make sure a blocking operation is executed to completion without getting
58 * interrupted. This should be used in cases where the operation is waiting fo r some critical
59 * work, e.g. cleanup, that must complete before returning. If the thread is i nterrupted during
60 * the blocking operation, this function will re-run the operation until compl etion, and only then
61 * re-interrupt the thread.
62 */
63 public static void executeUninterruptibly(BlockingOperation operation) {
64 boolean wasInterrupted = false;
65 while (true) {
66 try {
67 operation.run();
68 break;
69 } catch (InterruptedException e) {
70 // Someone is asking us to return early at our convenience. We can't can cel this operation,
71 // but we should preserve the information and pass it along.
72 wasInterrupted = true;
73 }
74 }
75 // Pass interruption information along.
76 if (wasInterrupted) {
77 Thread.currentThread().interrupt();
78 }
79 }
80
81 public static boolean joinUninterruptibly(final Thread thread, long timeoutMs) {
82 final long startTimeMs = SystemClock.elapsedRealtime();
83 long timeRemainingMs = timeoutMs;
84 boolean wasInterrupted = false;
85 while (timeRemainingMs > 0) {
86 try {
87 thread.join(timeRemainingMs);
88 break;
89 } catch (InterruptedException e) {
90 // Someone is asking us to return early at our convenience. We can't can cel this operation,
91 // but we should preserve the information and pass it along.
92 wasInterrupted = true;
93 final long elapsedTimeMs = SystemClock.elapsedRealtime() - startTimeMs;
94 timeRemainingMs = timeoutMs - elapsedTimeMs;
95 }
96 }
97 // Pass interruption information along.
98 if (wasInterrupted) {
99 Thread.currentThread().interrupt();
100 }
101 return !thread.isAlive();
102 }
103
104 public static void joinUninterruptibly(final Thread thread) {
105 executeUninterruptibly(new BlockingOperation() {
106 @Override
107 public void run() throws InterruptedException {
108 thread.join();
109 }
110 });
111 }
112
113 public static void awaitUninterruptibly(final CountDownLatch latch) {
114 executeUninterruptibly(new BlockingOperation() {
115 @Override
116 public void run() throws InterruptedException {
117 latch.await();
118 }
119 });
120 }
121
122 public static boolean awaitUninterruptibly(CountDownLatch barrier, long timeou tMs) {
123 final long startTimeMs = SystemClock.elapsedRealtime();
124 long timeRemainingMs = timeoutMs;
125 boolean wasInterrupted = false;
126 boolean result = false;
127 do {
128 try {
129 result = barrier.await(timeRemainingMs, TimeUnit.MILLISECONDS);
130 break;
131 } catch (InterruptedException e) {
132 // Someone is asking us to return early at our convenience. We can't can cel this operation,
133 // but we should preserve the information and pass it along.
134 wasInterrupted = true;
135 final long elapsedTimeMs = SystemClock.elapsedRealtime() - startTimeMs;
136 timeRemainingMs = timeoutMs - elapsedTimeMs;
137 }
138 } while (timeRemainingMs > 0);
139 // Pass interruption information along.
140 if (wasInterrupted) {
141 Thread.currentThread().interrupt();
142 }
143 return result;
144 }
145
146 public static void waitUninterruptibly(final Object object) {
147 executeUninterruptibly(new BlockingOperation() {
148 @Override
149 public void run() throws InterruptedException {
150 object.wait();
151 }
152 });
153 }
154
155 /**
156 * Post |callable| to |handler| and wait for the result.
157 */
158 public static <V> V invokeAtFrontUninterruptibly(
159 final Handler handler, final Callable<V> callable) {
160 if (handler.getLooper().getThread() == Thread.currentThread()) {
161 try {
162 return callable.call();
163 } catch (Exception e) {
164 throw new RuntimeException(e);
165 }
166 }
167 // Place-holder classes that are assignable inside nested class.
168 class CaughtException {
169 Exception e;
170 }
171 class Result {
172 public V value;
173 }
174 final Result result = new Result();
175 final CaughtException caughtException = new CaughtException();
176 final CountDownLatch barrier = new CountDownLatch(1);
177 handler.post(new Runnable() {
178 @Override
179 public void run() {
180 try {
181 result.value = callable.call();
182 } catch (Exception e) {
183 caughtException.e = e;
184 }
185 barrier.countDown();
186 }
187 });
188 awaitUninterruptibly(barrier);
189 // Re-throw any runtime exception caught inside the other thread. Since this is an invoke, add
190 // stack trace for the waiting thread as well.
191 if (caughtException.e != null) {
192 final RuntimeException runtimeException = new RuntimeException(caughtExcep tion.e);
193 runtimeException.setStackTrace(
194 concatStackTraces(caughtException.e.getStackTrace(), runtimeException. getStackTrace()));
195 throw runtimeException;
196 }
197 return result.value;
198 }
199
200 /**
201 * Post |runner| to |handler|, at the front, and wait for completion.
202 */
203 public static void invokeAtFrontUninterruptibly(final Handler handler, final R unnable runner) {
204 invokeAtFrontUninterruptibly(handler, new Callable<Void>() {
205 @Override
206 public Void call() {
207 runner.run();
208 return null;
209 }
210 });
211 }
212
213 static StackTraceElement[] concatStackTraces(
214 StackTraceElement[] inner, StackTraceElement[] outer) {
215 final StackTraceElement[] combined = new StackTraceElement[inner.length + ou ter.length];
216 System.arraycopy(inner, 0, combined, 0, inner.length);
217 System.arraycopy(outer, 0, combined, inner.length, outer.length);
218 return combined;
219 }
220 }
OLDNEW
« no previous file with comments | « webrtc/base/java/src/org/webrtc/Size.java ('k') | webrtc/base/json.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698