Chromium Code Reviews| Index: components/cronet/android/api/src/org/chromium/net/JavaUrlRequest.java |
| diff --git a/components/cronet/android/api/src/org/chromium/net/JavaUrlRequest.java b/components/cronet/android/api/src/org/chromium/net/JavaUrlRequest.java |
| index fe562799cda82ac2dda37922425f7e4ca9ba1ad6..f7126c2c5916215f99265623ae94c824a762a9a0 100644 |
| --- a/components/cronet/android/api/src/org/chromium/net/JavaUrlRequest.java |
| +++ b/components/cronet/android/api/src/org/chromium/net/JavaUrlRequest.java |
| @@ -56,6 +56,7 @@ final class JavaUrlRequest implements UrlRequest { |
| * exception), or cancellation. |
| */ |
| private final AtomicReference<State> mState = new AtomicReference<>(State.NOT_STARTED); |
| + private final AtomicBoolean mUploadProviderClosed = new AtomicBoolean(false); |
| /** |
| * Traffic stats tag to associate this requests' data use with. It's captured when the request |
| @@ -63,12 +64,12 @@ final class JavaUrlRequest implements UrlRequest { |
| * that data use. |
| */ |
| private final int mTrafficStatsTag; |
| + private final boolean mAllowDirectExecutor; |
| /* These don't change with redirects */ |
| private String mInitialMethod; |
| private UploadDataProvider mUploadDataProvider; |
| private Executor mUploadExecutor; |
| - private AtomicBoolean mUploadProviderClosed = new AtomicBoolean(false); |
| /** |
| * Holds a subset of StatusValues - {@link State#STARTED} can represent |
| @@ -120,7 +121,8 @@ final class JavaUrlRequest implements UrlRequest { |
| * @param userExecutor The executor used to dispatch to {@code callback} |
| */ |
| JavaUrlRequest(Callback callback, final Executor executor, Executor userExecutor, String url, |
| - String userAgent) { |
| + String userAgent, boolean allowDirectExecutor) { |
| + this.mAllowDirectExecutor = allowDirectExecutor; |
|
mef
2016/08/30 16:29:44
nit: move it to the end, below userAgent?
Charles
2016/08/30 20:11:06
This value gets read by AsyncUrlRequestCallback. M
|
| if (url == null) { |
| throw new NullPointerException("URL is required"); |
| } |
| @@ -237,7 +239,11 @@ final class JavaUrlRequest implements UrlRequest { |
| mInitialMethod = "POST"; |
| } |
| this.mUploadDataProvider = uploadDataProvider; |
| - this.mUploadExecutor = executor; |
| + if (mAllowDirectExecutor) { |
| + this.mUploadExecutor = executor; |
| + } else { |
| + this.mUploadExecutor = new DirectPreventingExecutor(executor); |
| + } |
| } |
| private enum SinkState { |
| @@ -299,12 +305,12 @@ final class JavaUrlRequest implements UrlRequest { |
| if (mWrittenBytes < mTotalBytes || (mTotalBytes == -1 && !finalChunk)) { |
| mBuffer.clear(); |
| mSinkState.set(SinkState.AWAITING_READ_RESULT); |
| - mUserExecutor.execute(uploadErrorSetting(new CheckedRunnable() { |
| + executeOnUploadExecutor(new CheckedRunnable() { |
| @Override |
| public void run() throws Exception { |
| mUploadProvider.read(OutputStreamDataSink.this, mBuffer); |
| } |
| - })); |
| + }); |
| } else if (mTotalBytes == -1) { |
| finish(); |
| } else if (mTotalBytes == mWrittenBytes) { |
| @@ -347,16 +353,24 @@ final class JavaUrlRequest implements UrlRequest { |
| mOutputChannel = Channels.newChannel(mUrlConnection.getOutputStream()); |
| } |
| mSinkState.set(SinkState.AWAITING_READ_RESULT); |
| - mUserExecutor.execute(uploadErrorSetting(new CheckedRunnable() { |
| + executeOnUploadExecutor(new CheckedRunnable() { |
| @Override |
| public void run() throws Exception { |
| mUploadProvider.read(OutputStreamDataSink.this, mBuffer); |
| } |
| - })); |
| + }); |
| } |
| })); |
| } |
| + private void executeOnUploadExecutor(CheckedRunnable runnable) { |
| + try { |
| + mUserExecutor.execute(uploadErrorSetting(runnable)); |
|
mef
2016/08/30 16:29:44
Should this execute on mUploadExecutor instead of
Charles
2016/08/30 20:11:05
In this lexical scope mUserExecutor is referring t
mef
2016/08/31 17:26:52
I see. I've missed the fact that this is part of O
Charles
2016/08/31 19:08:36
Done.
|
| + } catch (RejectedExecutionException e) { |
| + enterUploadErrorState(e); |
| + } |
| + } |
| + |
| void finish() throws IOException { |
| if (mOutputChannel != null) { |
| mOutputChannel.close(); |
| @@ -365,7 +379,7 @@ final class JavaUrlRequest implements UrlRequest { |
| } |
| void start(final boolean firstTime) { |
| - mUserExecutor.execute(uploadErrorSetting(new CheckedRunnable() { |
| + executeOnUploadExecutor(new CheckedRunnable() { |
| @Override |
| public void run() throws Exception { |
| mTotalBytes = mUploadProvider.getLength(); |
| @@ -401,7 +415,7 @@ final class JavaUrlRequest implements UrlRequest { |
| } |
| } |
| } |
| - })); |
| + }); |
| } |
| } |
| @@ -744,10 +758,17 @@ final class JavaUrlRequest implements UrlRequest { |
| private final class AsyncUrlRequestCallback { |
| final UrlRequest.Callback mCallback; |
| final Executor mUserExecutor; |
| + final Executor mFallbackExecutor; |
| AsyncUrlRequestCallback(Callback callback, final Executor userExecutor) { |
| this.mCallback = callback; |
| - this.mUserExecutor = userExecutor; |
| + if (mAllowDirectExecutor) { |
| + this.mUserExecutor = userExecutor; |
| + this.mFallbackExecutor = null; |
| + } else { |
| + mUserExecutor = new DirectPreventingExecutor(userExecutor); |
| + mFallbackExecutor = userExecutor; |
| + } |
| } |
| void sendStatus(final StatusListener listener, final int status) { |
| @@ -763,7 +784,8 @@ final class JavaUrlRequest implements UrlRequest { |
| try { |
| mUserExecutor.execute(userErrorSetting(currentState, runnable)); |
| } catch (RejectedExecutionException e) { |
| - enterUserErrorState(currentState, e); |
| + enterErrorState(currentState, |
| + new UrlRequestException("Exception posting task to executor", e)); |
| } |
| } |
| @@ -777,25 +799,25 @@ final class JavaUrlRequest implements UrlRequest { |
| } |
| void onResponseStarted(UrlResponseInfo info) { |
| - execute(State.AWAITING_READ, new CheckedRunnable() { |
| - @Override |
| - public void run() throws Exception { |
| - if (mState.compareAndSet(State.STARTED, State.AWAITING_READ)) { |
| + if (mState.compareAndSet(State.STARTED, State.AWAITING_READ)) { |
|
mef
2016/08/30 16:29:44
This is changing thread where mState is accessed f
Charles
2016/08/30 20:11:06
mState is safe from any thread, since it's an atom
mef
2016/08/31 17:26:52
Acknowledged.
|
| + execute(State.AWAITING_READ, new CheckedRunnable() { |
| + @Override |
| + public void run() throws Exception { |
| mCallback.onResponseStarted(JavaUrlRequest.this, mUrlResponseInfo); |
| } |
| - } |
| - }); |
| + }); |
| + } |
| } |
| void onReadCompleted(final UrlResponseInfo info, final ByteBuffer byteBuffer) { |
| - execute(State.AWAITING_READ, new CheckedRunnable() { |
| - @Override |
| - public void run() throws Exception { |
| - if (mState.compareAndSet(State.READING, State.AWAITING_READ)) { |
| + if (mState.compareAndSet(State.READING, State.AWAITING_READ)) { |
|
mef
2016/08/30 16:29:44
ditto.
Charles
2016/08/30 20:11:05
This one too - we want a REE thrown when submittin
|
| + execute(State.AWAITING_READ, new CheckedRunnable() { |
| + @Override |
| + public void run() throws Exception { |
| mCallback.onReadCompleted(JavaUrlRequest.this, info, byteBuffer); |
| } |
| - } |
| - }); |
| + }); |
| + } |
| } |
| void onCanceled(final UrlResponseInfo info) { |
| @@ -827,7 +849,7 @@ final class JavaUrlRequest implements UrlRequest { |
| void onFailed(final UrlResponseInfo urlResponseInfo, final UrlRequestException e) { |
| closeQuietly(mResponseChannel); |
| - mUserExecutor.execute(new Runnable() { |
| + Runnable runnable = new Runnable() { |
| @Override |
| public void run() { |
| try { |
| @@ -836,7 +858,14 @@ final class JavaUrlRequest implements UrlRequest { |
| Log.e(TAG, "Exception in onFailed method", exception); |
| } |
| } |
| - }); |
| + }; |
| + try { |
| + mUserExecutor.execute(runnable); |
| + } catch (InlineExecutionProhibitedException wasDirect) { |
| + if (mFallbackExecutor != null) { |
| + mFallbackExecutor.execute(runnable); |
| + } |
| + } |
| } |
| } |