Chromium Code Reviews| Index: components/cronet/android/api/src/org/chromium/net/DirectPreventingExecutor.java |
| diff --git a/components/cronet/android/api/src/org/chromium/net/DirectPreventingExecutor.java b/components/cronet/android/api/src/org/chromium/net/DirectPreventingExecutor.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..963f703e25be1a1a48589cac3dfba33d9f71bc5f |
| --- /dev/null |
| +++ b/components/cronet/android/api/src/org/chromium/net/DirectPreventingExecutor.java |
| @@ -0,0 +1,55 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package org.chromium.net; |
| + |
| +import java.util.concurrent.Executor; |
| + |
| +/** |
| + * Executor that detects and throws if its mDelegate runs a submitted runnable inline. |
| + */ |
| +final class DirectPreventingExecutor implements Executor { |
| + private final Executor mDelegate; |
| + |
| + DirectPreventingExecutor(Executor delegate) { |
| + this.mDelegate = delegate; |
| + } |
| + |
| + @Override |
| + public void execute(Runnable command) { |
| + Thread currentThread = Thread.currentThread(); |
| + InlineCheckingRunnable runnable = new InlineCheckingRunnable(command, currentThread); |
| + mDelegate.execute(runnable); |
| + if (runnable.mExecutedInline != null) { |
| + new RuntimeException(runnable.mExecutedInline).printStackTrace(); |
| + throw runnable.mExecutedInline; |
| + } else { |
| + // It's possible that this method is being called on an executor, and the runnable that |
| + // was just queued will run on this thread after the current runnable returns. By |
| + // nulling out the mCallingThread field, the InlineCheckingRunnable's current thread |
| + // comparison will not fire. |
| + runnable.mCallingThread = null; |
| + } |
| + } |
| + |
| + private static final class InlineCheckingRunnable implements Runnable { |
| + private final Runnable mCommand; |
| + private Thread mCallingThread; |
| + private InlineExecutionProhibitedException mExecutedInline = null; |
| + |
| + private InlineCheckingRunnable(Runnable command, Thread callingThread) { |
| + this.mCommand = command; |
| + this.mCallingThread = callingThread; |
| + } |
| + |
| + @Override |
| + public void run() { |
| + if (Thread.currentThread() == mCallingThread) { |
| + mExecutedInline = new InlineExecutionProhibitedException(); |
|
mef
2016/08/30 16:29:44
Can it just throw from here instead of returning?
Charles
2016/08/30 20:11:05
Done.
|
| + return; |
| + } |
| + mCommand.run(); |
| + } |
| + } |
| +} |