jimu-decompiled/sources/okhttp3/internal/connection/StreamAllocation.java
2025-05-13 19:24:51 +02:00

428 lines
15 KiB
Java

package okhttp3.internal.connection;
import java.io.IOException;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.net.Socket;
import java.util.List;
import okhttp3.Address;
import okhttp3.Call;
import okhttp3.ConnectionPool;
import okhttp3.EventListener;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Route;
import okhttp3.internal.Internal;
import okhttp3.internal.Util;
import okhttp3.internal.connection.RouteSelector;
import okhttp3.internal.http.HttpCodec;
import okhttp3.internal.http2.ConnectionShutdownException;
import okhttp3.internal.http2.ErrorCode;
import okhttp3.internal.http2.StreamResetException;
/* loaded from: classes2.dex */
public final class StreamAllocation {
static final /* synthetic */ boolean $assertionsDisabled = false;
public final Address address;
public final Call call;
private final Object callStackTrace;
private boolean canceled;
private HttpCodec codec;
private RealConnection connection;
private final ConnectionPool connectionPool;
public final EventListener eventListener;
private int refusedStreamCount;
private boolean released;
private boolean reportedAcquired;
private Route route;
private RouteSelector.Selection routeSelection;
private final RouteSelector routeSelector;
public static final class StreamAllocationReference extends WeakReference<StreamAllocation> {
public final Object callStackTrace;
StreamAllocationReference(StreamAllocation streamAllocation, Object obj) {
super(streamAllocation);
this.callStackTrace = obj;
}
}
public StreamAllocation(ConnectionPool connectionPool, Address address, Call call, EventListener eventListener, Object obj) {
this.connectionPool = connectionPool;
this.address = address;
this.call = call;
this.eventListener = eventListener;
this.routeSelector = new RouteSelector(address, routeDatabase(), call, eventListener);
this.callStackTrace = obj;
}
private Socket deallocate(boolean z, boolean z2, boolean z3) {
Socket socket;
if (z3) {
this.codec = null;
}
if (z2) {
this.released = true;
}
RealConnection realConnection = this.connection;
if (realConnection != null) {
if (z) {
realConnection.noNewStreams = true;
}
if (this.codec == null && (this.released || this.connection.noNewStreams)) {
release(this.connection);
if (this.connection.allocations.isEmpty()) {
this.connection.idleAtNanos = System.nanoTime();
if (Internal.instance.connectionBecameIdle(this.connectionPool, this.connection)) {
socket = this.connection.socket();
this.connection = null;
return socket;
}
}
socket = null;
this.connection = null;
return socket;
}
}
return null;
}
private RealConnection findConnection(int i, int i2, int i3, int i4, boolean z) throws IOException {
Socket releaseIfNoNewStreams;
Socket socket;
RealConnection realConnection;
RealConnection realConnection2;
RealConnection realConnection3;
Route route;
boolean z2;
boolean z3;
RouteSelector.Selection selection;
synchronized (this.connectionPool) {
if (this.released) {
throw new IllegalStateException("released");
}
if (this.codec != null) {
throw new IllegalStateException("codec != null");
}
if (this.canceled) {
throw new IOException("Canceled");
}
RealConnection realConnection4 = this.connection;
releaseIfNoNewStreams = releaseIfNoNewStreams();
socket = null;
if (this.connection != null) {
realConnection2 = this.connection;
realConnection = null;
} else {
realConnection = realConnection4;
realConnection2 = null;
}
if (!this.reportedAcquired) {
realConnection = null;
}
if (realConnection2 == null) {
Internal.instance.get(this.connectionPool, this.address, this, null);
if (this.connection != null) {
realConnection3 = this.connection;
route = null;
z2 = true;
} else {
route = this.route;
realConnection3 = realConnection2;
}
} else {
realConnection3 = realConnection2;
route = null;
}
z2 = false;
}
Util.closeQuietly(releaseIfNoNewStreams);
if (realConnection != null) {
this.eventListener.connectionReleased(this.call, realConnection);
}
if (z2) {
this.eventListener.connectionAcquired(this.call, realConnection3);
}
if (realConnection3 != null) {
return realConnection3;
}
if (route != null || ((selection = this.routeSelection) != null && selection.hasNext())) {
z3 = false;
} else {
this.routeSelection = this.routeSelector.next();
z3 = true;
}
synchronized (this.connectionPool) {
if (this.canceled) {
throw new IOException("Canceled");
}
if (z3) {
List<Route> all = this.routeSelection.getAll();
int size = all.size();
int i5 = 0;
while (true) {
if (i5 >= size) {
break;
}
Route route2 = all.get(i5);
Internal.instance.get(this.connectionPool, this.address, this, route2);
if (this.connection != null) {
realConnection3 = this.connection;
this.route = route2;
z2 = true;
break;
}
i5++;
}
}
if (!z2) {
if (route == null) {
route = this.routeSelection.next();
}
this.route = route;
this.refusedStreamCount = 0;
realConnection3 = new RealConnection(this.connectionPool, route);
acquire(realConnection3, false);
}
}
if (z2) {
this.eventListener.connectionAcquired(this.call, realConnection3);
return realConnection3;
}
realConnection3.connect(i, i2, i3, i4, z, this.call, this.eventListener);
routeDatabase().connected(realConnection3.route());
synchronized (this.connectionPool) {
this.reportedAcquired = true;
Internal.instance.put(this.connectionPool, realConnection3);
if (realConnection3.isMultiplexed()) {
socket = Internal.instance.deduplicate(this.connectionPool, this.address, this);
realConnection3 = this.connection;
}
}
Util.closeQuietly(socket);
this.eventListener.connectionAcquired(this.call, realConnection3);
return realConnection3;
}
private RealConnection findHealthyConnection(int i, int i2, int i3, int i4, boolean z, boolean z2) throws IOException {
while (true) {
RealConnection findConnection = findConnection(i, i2, i3, i4, z);
synchronized (this.connectionPool) {
if (findConnection.successCount == 0) {
return findConnection;
}
if (findConnection.isHealthy(z2)) {
return findConnection;
}
noNewStreams();
}
}
}
private Socket releaseIfNoNewStreams() {
RealConnection realConnection = this.connection;
if (realConnection == null || !realConnection.noNewStreams) {
return null;
}
return deallocate(false, false, true);
}
private RouteDatabase routeDatabase() {
return Internal.instance.routeDatabase(this.connectionPool);
}
public void acquire(RealConnection realConnection, boolean z) {
if (this.connection != null) {
throw new IllegalStateException();
}
this.connection = realConnection;
this.reportedAcquired = z;
realConnection.allocations.add(new StreamAllocationReference(this, this.callStackTrace));
}
public void cancel() {
HttpCodec httpCodec;
RealConnection realConnection;
synchronized (this.connectionPool) {
this.canceled = true;
httpCodec = this.codec;
realConnection = this.connection;
}
if (httpCodec != null) {
httpCodec.cancel();
} else if (realConnection != null) {
realConnection.cancel();
}
}
public HttpCodec codec() {
HttpCodec httpCodec;
synchronized (this.connectionPool) {
httpCodec = this.codec;
}
return httpCodec;
}
public synchronized RealConnection connection() {
return this.connection;
}
public boolean hasMoreRoutes() {
RouteSelector.Selection selection;
return this.route != null || ((selection = this.routeSelection) != null && selection.hasNext()) || this.routeSelector.hasNext();
}
public HttpCodec newStream(OkHttpClient okHttpClient, Interceptor.Chain chain, boolean z) {
try {
HttpCodec newCodec = findHealthyConnection(chain.connectTimeoutMillis(), chain.readTimeoutMillis(), chain.writeTimeoutMillis(), okHttpClient.pingIntervalMillis(), okHttpClient.retryOnConnectionFailure(), z).newCodec(okHttpClient, chain, this);
synchronized (this.connectionPool) {
this.codec = newCodec;
}
return newCodec;
} catch (IOException e) {
throw new RouteException(e);
}
}
public void noNewStreams() {
RealConnection realConnection;
Socket deallocate;
synchronized (this.connectionPool) {
realConnection = this.connection;
deallocate = deallocate(true, false, false);
if (this.connection != null) {
realConnection = null;
}
}
Util.closeQuietly(deallocate);
if (realConnection != null) {
this.eventListener.connectionReleased(this.call, realConnection);
}
}
public void release() {
RealConnection realConnection;
Socket deallocate;
synchronized (this.connectionPool) {
realConnection = this.connection;
deallocate = deallocate(false, true, false);
if (this.connection != null) {
realConnection = null;
}
}
Util.closeQuietly(deallocate);
if (realConnection != null) {
this.eventListener.connectionReleased(this.call, realConnection);
this.eventListener.callEnd(this.call);
}
}
public Socket releaseAndAcquire(RealConnection realConnection) {
if (this.codec != null || this.connection.allocations.size() != 1) {
throw new IllegalStateException();
}
Reference<StreamAllocation> reference = this.connection.allocations.get(0);
Socket deallocate = deallocate(true, false, false);
this.connection = realConnection;
realConnection.allocations.add(reference);
return deallocate;
}
public Route route() {
return this.route;
}
public void streamFailed(IOException iOException) {
boolean z;
RealConnection realConnection;
Socket deallocate;
synchronized (this.connectionPool) {
if (iOException instanceof StreamResetException) {
ErrorCode errorCode = ((StreamResetException) iOException).errorCode;
if (errorCode == ErrorCode.REFUSED_STREAM) {
this.refusedStreamCount++;
if (this.refusedStreamCount > 1) {
this.route = null;
z = true;
}
z = false;
} else {
if (errorCode != ErrorCode.CANCEL) {
this.route = null;
z = true;
}
z = false;
}
} else {
if (this.connection != null && (!this.connection.isMultiplexed() || (iOException instanceof ConnectionShutdownException))) {
if (this.connection.successCount == 0) {
if (this.route != null && iOException != null) {
this.routeSelector.connectFailed(this.route, iOException);
}
this.route = null;
}
z = true;
}
z = false;
}
realConnection = this.connection;
deallocate = deallocate(z, false, true);
if (this.connection != null || !this.reportedAcquired) {
realConnection = null;
}
}
Util.closeQuietly(deallocate);
if (realConnection != null) {
this.eventListener.connectionReleased(this.call, realConnection);
}
}
public void streamFinished(boolean z, HttpCodec httpCodec, long j, IOException iOException) {
RealConnection realConnection;
Socket deallocate;
boolean z2;
this.eventListener.responseBodyEnd(this.call, j);
synchronized (this.connectionPool) {
if (httpCodec != null) {
if (httpCodec == this.codec) {
if (!z) {
this.connection.successCount++;
}
realConnection = this.connection;
deallocate = deallocate(z, false, true);
if (this.connection != null) {
realConnection = null;
}
z2 = this.released;
}
}
throw new IllegalStateException("expected " + this.codec + " but was " + httpCodec);
}
Util.closeQuietly(deallocate);
if (realConnection != null) {
this.eventListener.connectionReleased(this.call, realConnection);
}
if (iOException != null) {
this.eventListener.callFailed(this.call, iOException);
} else if (z2) {
this.eventListener.callEnd(this.call);
}
}
public String toString() {
RealConnection connection = connection();
return connection != null ? connection.toString() : this.address.toString();
}
private void release(RealConnection realConnection) {
int size = realConnection.allocations.size();
for (int i = 0; i < size; i++) {
if (realConnection.allocations.get(i).get() == this) {
realConnection.allocations.remove(i);
return;
}
}
throw new IllegalStateException();
}
}