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

Side by Side Diff: components/cronet/android/java/src/org/chromium/net/urlconnection/MessageLoop.java

Issue 1984723002: Support setReadTimeout in CronetHttpURLConnection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address John's comments Created 4 years, 7 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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.urlconnection; 5 package org.chromium.net.urlconnection;
6 6
7 import java.io.IOException; 7 import java.io.IOException;
8 import java.io.InterruptedIOException;
9 import java.net.SocketTimeoutException;
8 import java.util.concurrent.BlockingQueue; 10 import java.util.concurrent.BlockingQueue;
9 import java.util.concurrent.Executor; 11 import java.util.concurrent.Executor;
10 import java.util.concurrent.LinkedBlockingQueue; 12 import java.util.concurrent.LinkedBlockingQueue;
11 import java.util.concurrent.RejectedExecutionException; 13 import java.util.concurrent.RejectedExecutionException;
14 import java.util.concurrent.TimeUnit;
12 15
13 /** 16 /**
14 * A MessageLoop class for use in {@link CronetHttpURLConnection}. 17 * A MessageLoop class for use in {@link CronetHttpURLConnection}.
15 */ 18 */
16 class MessageLoop implements Executor { 19 class MessageLoop implements Executor {
17 private final BlockingQueue<Runnable> mQueue; 20 private final BlockingQueue<Runnable> mQueue;
18 21
19 // Indicates whether this message loop is currently running. 22 // Indicates whether this message loop is currently running.
20 private boolean mLoopRunning = false; 23 private boolean mLoopRunning = false;
21 24
(...skipping 13 matching lines...) Expand all
35 38
36 private boolean calledOnValidThread() { 39 private boolean calledOnValidThread() {
37 if (mThreadId == INVALID_THREAD_ID) { 40 if (mThreadId == INVALID_THREAD_ID) {
38 mThreadId = Thread.currentThread().getId(); 41 mThreadId = Thread.currentThread().getId();
39 return true; 42 return true;
40 } 43 }
41 return mThreadId == Thread.currentThread().getId(); 44 return mThreadId == Thread.currentThread().getId();
42 } 45 }
43 46
44 /** 47 /**
48 * Retrieves a task from the queue with the given timeout.
49 *
50 * @param useTimeout whether to use a timeout.
51 * @param timeout Time to wait, in milliseconds.
52 * @return A non-{@code null} Runnable from the queue.
53 * @throws InterruptedIOException
54 */
55 private Runnable take(boolean useTimeout, int timeout) throws InterruptedIOE xception {
kapishnikov 2016/05/18 01:13:42 Should we change the timeout type in this method t
xunjieli 2016/05/18 13:31:27 Done.
56 Runnable task = null;
57 try {
58 if (!useTimeout) {
59 task = mQueue.take(); // Blocks if the queue is empty.
60 } else {
61 // poll returns null upon timeout.
62 task = mQueue.poll(timeout, TimeUnit.MILLISECONDS);
63 }
64 } catch (InterruptedException e) {
65 InterruptedIOException exception = new InterruptedIOException();
66 exception.initCause(e);
67 throw exception;
68 }
69 if (task == null) {
70 // This will terminate the loop.
71 throw new SocketTimeoutException();
72 }
73 return task;
74 }
75
76 /**
45 * Runs the message loop. Be sure to call {@link MessageLoop#quit()} 77 * Runs the message loop. Be sure to call {@link MessageLoop#quit()}
46 * to end the loop. If an interruptedException occurs, the loop cannot be 78 * to end the loop. If an interruptedException occurs, the loop cannot be
47 * started again (see {@link #mLoopFailed}). 79 * started again (see {@link #mLoopFailed}).
48 * @throws IOException 80 * @throws IOException
49 */ 81 */
50 public void loop() throws IOException { 82 public void loop() throws IOException {
83 loop(0);
84 }
85
86 /**
87 * Runs the message loop. Be sure to call {@link MessageLoop#quit()}
88 * to end the loop. If an interruptedException occurs, the loop cannot be
89 * started again (see {@link #mLoopFailed}).
90 * @param timeout Timeout, in milliseconds, or 0 for no timeout.
91 * @throws IOException
92 */
93 public void loop(int timeout) throws IOException {
51 assert calledOnValidThread(); 94 assert calledOnValidThread();
95 long start = System.currentTimeMillis();
kapishnikov 2016/05/18 01:13:43 It is better to use System.nanoTime(), which retur
xunjieli 2016/05/18 13:31:27 Done.
52 if (mLoopFailed) { 96 if (mLoopFailed) {
53 throw new IllegalStateException( 97 throw new IllegalStateException(
54 "Cannot run loop as an exception has occurred previously."); 98 "Cannot run loop as an exception has occurred previously.");
55 } 99 }
56 if (mLoopRunning) { 100 if (mLoopRunning) {
57 throw new IllegalStateException( 101 throw new IllegalStateException(
58 "Cannot run loop when it is already running."); 102 "Cannot run loop when it is already running.");
59 } 103 }
60 mLoopRunning = true; 104 mLoopRunning = true;
61 while (mLoopRunning) { 105 while (mLoopRunning) {
62 try { 106 try {
63 Runnable task = mQueue.take(); // Blocks if the queue is empty. 107 if (timeout == 0) {
64 task.run(); 108 take(false, timeout);
kapishnikov 2016/05/18 01:13:42 Better take(false, 0)
xunjieli 2016/05/18 13:31:27 Done.
65 } catch (InterruptedException | RuntimeException e) { 109 } else {
110 long timeElapsed = System.currentTimeMillis() - start;
111 // Make sure overflow won't happen when casting timeElapsed to an int.
112 if (timeElapsed > timeout) {
113 throw new SocketTimeoutException();
114 }
115 // Will system clock run backwards?
116 if (timeElapsed < 0) {
kapishnikov 2016/05/18 01:13:42 This should not be possible with System.nanoTime()
xunjieli 2016/05/18 13:31:27 Done.
117 timeElapsed = 0;
118 }
119 take(true, timeout - (int) timeElapsed).run();
120 }
121 } catch (InterruptedIOException | RuntimeException e) {
66 mLoopRunning = false; 122 mLoopRunning = false;
67 mLoopFailed = true; 123 mLoopFailed = true;
68 if (e instanceof InterruptedException) { 124 throw e;
69 throw new IOException(e);
70 } else if (e instanceof RuntimeException) {
71 throw (RuntimeException) e;
72 }
73 } 125 }
74 } 126 }
75 } 127 }
76 128
77 /** 129 /**
78 * This causes {@link #loop()} to stop executing messages after the current 130 * This causes {@link #loop()} to stop executing messages after the current
79 * message being executed. Should only be called from the currently 131 * message being executed. Should only be called from the currently
80 * executing message. 132 * executing message.
81 */ 133 */
82 public void quit() { 134 public void quit() {
(...skipping 25 matching lines...) Expand all
108 return mLoopRunning; 160 return mLoopRunning;
109 } 161 }
110 162
111 /** 163 /**
112 * Returns whether an exception occurred in {#loop()}. Used in testing. 164 * Returns whether an exception occurred in {#loop()}. Used in testing.
113 */ 165 */
114 public boolean hasLoopFailed() { 166 public boolean hasLoopFailed() {
115 return mLoopFailed; 167 return mLoopFailed;
116 } 168 }
117 } 169 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698