Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.net.impl; | 5 package org.chromium.net.impl; |
| 6 | 6 |
| 7 import android.annotation.SuppressLint; | 7 import android.annotation.SuppressLint; |
| 8 import android.annotation.TargetApi; | 8 import android.annotation.TargetApi; |
| 9 import android.net.TrafficStats; | 9 import android.net.TrafficStats; |
| 10 import android.os.Build; | 10 import android.os.Build; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 import java.net.HttpURLConnection; | 23 import java.net.HttpURLConnection; |
| 24 import java.net.URI; | 24 import java.net.URI; |
| 25 import java.net.URL; | 25 import java.net.URL; |
| 26 import java.nio.ByteBuffer; | 26 import java.nio.ByteBuffer; |
| 27 import java.nio.channels.Channels; | 27 import java.nio.channels.Channels; |
| 28 import java.nio.channels.ReadableByteChannel; | 28 import java.nio.channels.ReadableByteChannel; |
| 29 import java.nio.channels.WritableByteChannel; | 29 import java.nio.channels.WritableByteChannel; |
| 30 import java.util.AbstractMap.SimpleEntry; | 30 import java.util.AbstractMap.SimpleEntry; |
| 31 import java.util.ArrayList; | 31 import java.util.ArrayList; |
| 32 import java.util.Collections; | 32 import java.util.Collections; |
| 33 import java.util.LinkedList; | |
| 33 import java.util.List; | 34 import java.util.List; |
| 34 import java.util.Map; | 35 import java.util.Map; |
| 35 import java.util.TreeMap; | 36 import java.util.TreeMap; |
| 36 import java.util.concurrent.Executor; | 37 import java.util.concurrent.Executor; |
| 37 import java.util.concurrent.RejectedExecutionException; | 38 import java.util.concurrent.RejectedExecutionException; |
| 38 import java.util.concurrent.atomic.AtomicBoolean; | 39 import java.util.concurrent.atomic.AtomicBoolean; |
| 39 import java.util.concurrent.atomic.AtomicReference; | 40 import java.util.concurrent.atomic.AtomicReference; |
| 40 | 41 |
| 41 /** | 42 /** |
| 42 * Pure java UrlRequest, backed by {@link HttpURLConnection}. | 43 * Pure java UrlRequest, backed by {@link HttpURLConnection}. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 STARTED, | 120 STARTED, |
| 120 REDIRECT_RECEIVED, | 121 REDIRECT_RECEIVED, |
| 121 AWAITING_FOLLOW_REDIRECT, | 122 AWAITING_FOLLOW_REDIRECT, |
| 122 AWAITING_READ, | 123 AWAITING_READ, |
| 123 READING, | 124 READING, |
| 124 ERROR, | 125 ERROR, |
| 125 COMPLETE, | 126 COMPLETE, |
| 126 CANCELLED, | 127 CANCELLED, |
| 127 } | 128 } |
| 128 | 129 |
| 130 // Executor that runs one task at a time on an underlying Executor. | |
| 131 private class SeriaizingExecutor implements Executor { | |
| 132 private final Executor mUnderlyingExecutor; | |
| 133 // Queue of tasks to run. First element is the task currently executing . | |
| 134 // Task processing loop is running if queue is not empty. Synchronized on itself. | |
| 135 private final List<Runnable> mTaskQueue = new LinkedList<>(); | |
|
Charles
2017/01/07 03:48:06
Also @GuardedBy
Charles
2017/01/07 03:48:06
Use an ArrayDeque instead - faster, offers methods
pauljensen
2017/01/11 15:29:58
Done.
pauljensen
2017/01/11 15:29:58
Done.
| |
| 136 | |
| 137 public SeriaizingExecutor(Executor underlyingExecutor) { | |
| 138 mUnderlyingExecutor = underlyingExecutor; | |
| 139 } | |
| 140 | |
| 141 @Override | |
| 142 public void execute(final Runnable command) { | |
| 143 synchronized (mTaskQueue) { | |
| 144 mTaskQueue.add(command); | |
| 145 // Task processing loop is already running if there are other it ems in mTaskQueue. | |
| 146 if (mTaskQueue.size() > 1) { | |
| 147 return; | |
| 148 } | |
| 149 } | |
| 150 mUnderlyingExecutor.execute(new Runnable() { | |
| 151 @Override | |
| 152 public void run() { | |
| 153 Runnable task = command; | |
| 154 while (true) { | |
| 155 task.run(); | |
|
Charles
2017/01/07 03:48:06
If this throws an exception, other submitted tasks
pauljensen
2017/01/11 15:29:58
Done, note that the Runnables can only be submitte
| |
| 156 synchronized (mTaskQueue) { | |
| 157 mTaskQueue.remove(0); | |
| 158 if (mTaskQueue.isEmpty()) { | |
| 159 return; | |
| 160 } | |
| 161 task = mTaskQueue.get(0); | |
| 162 } | |
| 163 } | |
| 164 } | |
| 165 }); | |
| 166 }; | |
| 167 } | |
| 168 | |
| 129 /** | 169 /** |
| 130 * @param executor The executor used for reading and writing from sockets | 170 * @param executor The executor used for reading and writing from sockets |
| 131 * @param userExecutor The executor used to dispatch to {@code callback} | 171 * @param userExecutor The executor used to dispatch to {@code callback} |
| 132 */ | 172 */ |
| 133 JavaUrlRequest(Callback callback, final Executor executor, Executor userExec utor, String url, | 173 JavaUrlRequest(Callback callback, final Executor executor, Executor userExec utor, String url, |
| 134 String userAgent, boolean allowDirectExecutor) { | 174 String userAgent, boolean allowDirectExecutor) { |
| 135 if (url == null) { | 175 if (url == null) { |
| 136 throw new NullPointerException("URL is required"); | 176 throw new NullPointerException("URL is required"); |
| 137 } | 177 } |
| 138 if (callback == null) { | 178 if (callback == null) { |
| 139 throw new NullPointerException("Listener is required"); | 179 throw new NullPointerException("Listener is required"); |
| 140 } | 180 } |
| 141 if (executor == null) { | 181 if (executor == null) { |
| 142 throw new NullPointerException("Executor is required"); | 182 throw new NullPointerException("Executor is required"); |
| 143 } | 183 } |
| 144 if (userExecutor == null) { | 184 if (userExecutor == null) { |
| 145 throw new NullPointerException("userExecutor is required"); | 185 throw new NullPointerException("userExecutor is required"); |
| 146 } | 186 } |
| 147 | 187 |
| 148 this.mAllowDirectExecutor = allowDirectExecutor; | 188 this.mAllowDirectExecutor = allowDirectExecutor; |
| 149 this.mCallbackAsync = new AsyncUrlRequestCallback(callback, userExecutor ); | 189 this.mCallbackAsync = new AsyncUrlRequestCallback(callback, userExecutor ); |
| 150 this.mTrafficStatsTag = TrafficStats.getThreadStatsTag(); | 190 this.mTrafficStatsTag = TrafficStats.getThreadStatsTag(); |
| 151 this.mExecutor = new Executor() { | 191 this.mExecutor = new SeriaizingExecutor(new Executor() { |
| 152 @Override | 192 @Override |
| 153 public void execute(final Runnable command) { | 193 public void execute(final Runnable command) { |
| 154 executor.execute(new Runnable() { | 194 executor.execute(new Runnable() { |
| 155 @Override | 195 @Override |
| 156 public void run() { | 196 public void run() { |
| 157 int oldTag = TrafficStats.getThreadStatsTag(); | 197 int oldTag = TrafficStats.getThreadStatsTag(); |
| 158 TrafficStats.setThreadStatsTag(mTrafficStatsTag); | 198 TrafficStats.setThreadStatsTag(mTrafficStatsTag); |
| 159 try { | 199 try { |
| 160 command.run(); | 200 command.run(); |
| 161 } finally { | 201 } finally { |
| 162 TrafficStats.setThreadStatsTag(oldTag); | 202 TrafficStats.setThreadStatsTag(oldTag); |
| 163 } | 203 } |
| 164 } | 204 } |
| 165 }); | 205 }); |
| 166 } | 206 } |
| 167 }; | 207 }); |
| 168 this.mCurrentUrl = url; | 208 this.mCurrentUrl = url; |
| 169 this.mUserAgent = userAgent; | 209 this.mUserAgent = userAgent; |
| 170 } | 210 } |
| 171 | 211 |
| 172 @Override | 212 @Override |
| 173 public void setHttpMethod(String method) { | 213 public void setHttpMethod(String method) { |
| 174 checkNotStarted(); | 214 checkNotStarted(); |
| 175 if (method == null) { | 215 if (method == null) { |
| 176 throw new NullPointerException("Method is required."); | 216 throw new NullPointerException("Method is required."); |
| 177 } | 217 } |
| (...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 972 // Can't throw directly from here, since the delegate execut or could catch this | 1012 // Can't throw directly from here, since the delegate execut or could catch this |
| 973 // exception. | 1013 // exception. |
| 974 mExecutedInline = new InlineExecutionProhibitedException(); | 1014 mExecutedInline = new InlineExecutionProhibitedException(); |
| 975 return; | 1015 return; |
| 976 } | 1016 } |
| 977 mCommand.run(); | 1017 mCommand.run(); |
| 978 } | 1018 } |
| 979 } | 1019 } |
| 980 } | 1020 } |
| 981 } | 1021 } |
| OLD | NEW |