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

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: remove outdated include 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 timeoutNano Time to wait, in nanoseconds.
52 * @return A non-{@code null} Runnable from the queue.
53 * @throws InterruptedIOException
54 */
55 private Runnable take(boolean useTimeout, long timeoutNano) throws Interrupt edIOException {
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(timeoutNano, TimeUnit.NANOSECONDS);
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 timeoutMilli Timeout, in milliseconds, or 0 for no timeout.
91 * @throws IOException
92 */
93 public void loop(int timeoutMilli) throws IOException {
51 assert calledOnValidThread(); 94 assert calledOnValidThread();
95 // Use System.nanoTime() which is monotonically increasing.
96 long startNano = System.nanoTime();
97 long timeoutNano = TimeUnit.NANOSECONDS.convert(timeoutMilli, TimeUnit.M ILLISECONDS);
52 if (mLoopFailed) { 98 if (mLoopFailed) {
53 throw new IllegalStateException( 99 throw new IllegalStateException(
54 "Cannot run loop as an exception has occurred previously."); 100 "Cannot run loop as an exception has occurred previously.");
55 } 101 }
56 if (mLoopRunning) { 102 if (mLoopRunning) {
57 throw new IllegalStateException( 103 throw new IllegalStateException(
58 "Cannot run loop when it is already running."); 104 "Cannot run loop when it is already running.");
59 } 105 }
60 mLoopRunning = true; 106 mLoopRunning = true;
61 while (mLoopRunning) { 107 while (mLoopRunning) {
62 try { 108 try {
63 Runnable task = mQueue.take(); // Blocks if the queue is empty. 109 if (timeoutMilli == 0) {
64 task.run(); 110 take(false, 0).run();
65 } catch (InterruptedException | RuntimeException e) { 111 } else {
112 take(true, timeoutNano - System.nanoTime() + startNano).run( );
113 }
114 } catch (InterruptedIOException | RuntimeException e) {
66 mLoopRunning = false; 115 mLoopRunning = false;
67 mLoopFailed = true; 116 mLoopFailed = true;
68 if (e instanceof InterruptedException) { 117 throw e;
69 throw new IOException(e);
70 } else if (e instanceof RuntimeException) {
71 throw (RuntimeException) e;
72 }
73 } 118 }
74 } 119 }
75 } 120 }
76 121
77 /** 122 /**
78 * This causes {@link #loop()} to stop executing messages after the current 123 * This causes {@link #loop()} to stop executing messages after the current
79 * message being executed. Should only be called from the currently 124 * message being executed. Should only be called from the currently
80 * executing message. 125 * executing message.
81 */ 126 */
82 public void quit() { 127 public void quit() {
(...skipping 25 matching lines...) Expand all
108 return mLoopRunning; 153 return mLoopRunning;
109 } 154 }
110 155
111 /** 156 /**
112 * Returns whether an exception occurred in {#loop()}. Used in testing. 157 * Returns whether an exception occurred in {#loop()}. Used in testing.
113 */ 158 */
114 public boolean hasLoopFailed() { 159 public boolean hasLoopFailed() {
115 return mLoopFailed; 160 return mLoopFailed;
116 } 161 }
117 } 162 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698