what-the-bank/sources/io/grpc/okhttp/OutboundFlowController.java

264 lines
9.7 KiB
Java
Raw Permalink Normal View History

2024-07-27 18:17:47 +07:00
package io.grpc.okhttp;
import com.google.common.base.Preconditions;
import io.grpc.okhttp.internal.framed.FrameWriter;
import java.io.IOException;
import o.C15111ghZ;
/* JADX INFO: Access modifiers changed from: package-private */
/* loaded from: classes6.dex */
public class OutboundFlowController {
private final FrameWriter frameWriter;
private final OkHttpClientTransport transport;
private int initialWindowSize = 65535;
private final OutboundFlowState connectionState = new OutboundFlowState(this, 0, 65535);
/* JADX INFO: Access modifiers changed from: package-private */
public OutboundFlowController(OkHttpClientTransport okHttpClientTransport, FrameWriter frameWriter) {
this.transport = (OkHttpClientTransport) Preconditions.checkNotNull(okHttpClientTransport, "transport");
this.frameWriter = (FrameWriter) Preconditions.checkNotNull(frameWriter, "frameWriter");
}
/* JADX INFO: Access modifiers changed from: package-private */
public boolean initialOutboundWindowSize(int i) {
if (i < 0) {
throw new IllegalArgumentException("Invalid initial window size: ".concat(String.valueOf(i)));
}
int i2 = i - this.initialWindowSize;
this.initialWindowSize = i;
for (OkHttpClientStream okHttpClientStream : this.transport.getActiveStreams()) {
OutboundFlowState outboundFlowState = (OutboundFlowState) okHttpClientStream.getOutboundFlowState();
if (outboundFlowState == null) {
okHttpClientStream.setOutboundFlowState(new OutboundFlowState(this, okHttpClientStream, this.initialWindowSize));
} else {
outboundFlowState.incrementStreamWindow(i2);
}
}
return i2 > 0;
}
/* JADX INFO: Access modifiers changed from: package-private */
public int windowUpdate(OkHttpClientStream okHttpClientStream, int i) {
if (okHttpClientStream == null) {
int incrementStreamWindow = this.connectionState.incrementStreamWindow(i);
writeStreams();
return incrementStreamWindow;
}
OutboundFlowState state = state(okHttpClientStream);
int incrementStreamWindow2 = state.incrementStreamWindow(i);
WriteStatus writeStatus = new WriteStatus();
state.writeBytes(state.writableWindow(), writeStatus);
if (writeStatus.hasWritten()) {
flush();
}
return incrementStreamWindow2;
}
/* JADX INFO: Access modifiers changed from: package-private */
public void data(boolean z, int i, C15111ghZ c15111ghZ, boolean z2) {
Preconditions.checkNotNull(c15111ghZ, "source");
OkHttpClientStream stream = this.transport.getStream(i);
if (stream == null) {
return;
}
OutboundFlowState state = state(stream);
int writableWindow = state.writableWindow();
boolean hasPendingData = state.hasPendingData();
int i2 = (int) c15111ghZ.c;
if (!hasPendingData && writableWindow >= i2) {
state.write(c15111ghZ, i2, z);
} else {
if (!hasPendingData && writableWindow > 0) {
state.write(c15111ghZ, writableWindow, false);
}
state.enqueue(c15111ghZ, (int) c15111ghZ.c, z);
}
if (z2) {
flush();
}
}
void flush() {
try {
this.frameWriter.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private OutboundFlowState state(OkHttpClientStream okHttpClientStream) {
OutboundFlowState outboundFlowState = (OutboundFlowState) okHttpClientStream.getOutboundFlowState();
if (outboundFlowState != null) {
return outboundFlowState;
}
OutboundFlowState outboundFlowState2 = new OutboundFlowState(this, okHttpClientStream, this.initialWindowSize);
okHttpClientStream.setOutboundFlowState(outboundFlowState2);
return outboundFlowState2;
}
/* JADX INFO: Access modifiers changed from: package-private */
public void writeStreams() {
int i;
OkHttpClientStream[] activeStreams = this.transport.getActiveStreams();
int window = this.connectionState.window();
int length = activeStreams.length;
while (true) {
i = 0;
if (length <= 0 || window <= 0) {
break;
}
int ceil = (int) Math.ceil(window / length);
for (int i2 = 0; i2 < length && window > 0; i2++) {
OkHttpClientStream okHttpClientStream = activeStreams[i2];
OutboundFlowState state = state(okHttpClientStream);
int min = Math.min(window, Math.min(state.unallocatedBytes(), ceil));
if (min > 0) {
state.allocateBytes(min);
window -= min;
}
if (state.unallocatedBytes() > 0) {
activeStreams[i] = okHttpClientStream;
i++;
}
}
length = i;
}
WriteStatus writeStatus = new WriteStatus();
OkHttpClientStream[] activeStreams2 = this.transport.getActiveStreams();
int length2 = activeStreams2.length;
while (i < length2) {
OutboundFlowState state2 = state(activeStreams2[i]);
state2.writeBytes(state2.allocatedBytes(), writeStatus);
state2.clearAllocatedBytes();
i++;
}
if (writeStatus.hasWritten()) {
flush();
}
}
/* JADX INFO: Access modifiers changed from: package-private */
/* loaded from: classes6.dex */
public static final class WriteStatus {
int numWrites;
private WriteStatus() {
}
final void incrementNumWrites() {
this.numWrites++;
}
final boolean hasWritten() {
return this.numWrites > 0;
}
}
/* JADX INFO: Access modifiers changed from: package-private */
/* loaded from: classes6.dex */
public final class OutboundFlowState {
int allocatedBytes;
boolean pendingBufferHasEndOfStream;
final C15111ghZ pendingWriteBuffer;
OkHttpClientStream stream;
final int streamId;
final OutboundFlowController this$0;
int window;
OutboundFlowState(OutboundFlowController outboundFlowController, int i, int i2) {
this.this$0 = outboundFlowController;
this.pendingBufferHasEndOfStream = false;
this.streamId = i;
this.window = i2;
this.pendingWriteBuffer = new C15111ghZ();
}
OutboundFlowState(OutboundFlowController outboundFlowController, OkHttpClientStream okHttpClientStream, int i) {
this(outboundFlowController, okHttpClientStream.id(), i);
this.stream = okHttpClientStream;
}
final int unallocatedBytes() {
return streamableBytes() - this.allocatedBytes;
}
final int incrementStreamWindow(int i) {
if (i <= 0 || Integer.MAX_VALUE - i >= this.window) {
int i2 = this.window + i;
this.window = i2;
return i2;
}
StringBuilder sb = new StringBuilder("Window size overflow for stream: ");
sb.append(this.streamId);
throw new IllegalArgumentException(sb.toString());
}
final int writableWindow() {
return Math.min(this.window, this.this$0.connectionState.window());
}
final int writeBytes(int i, WriteStatus writeStatus) {
int min = Math.min(i, writableWindow());
int i2 = 0;
while (hasPendingData() && min > 0) {
if (min < this.pendingWriteBuffer.c) {
i2 += min;
write(this.pendingWriteBuffer, min, false);
} else {
i2 += (int) this.pendingWriteBuffer.c;
C15111ghZ c15111ghZ = this.pendingWriteBuffer;
write(c15111ghZ, (int) c15111ghZ.c, this.pendingBufferHasEndOfStream);
}
writeStatus.incrementNumWrites();
min = Math.min(i - i2, writableWindow());
}
return i2;
}
final void write(C15111ghZ c15111ghZ, int i, boolean z) {
do {
int min = Math.min(i, this.this$0.frameWriter.maxDataLength());
int i2 = -min;
this.this$0.connectionState.incrementStreamWindow(i2);
incrementStreamWindow(i2);
try {
this.this$0.frameWriter.data(c15111ghZ.c == ((long) min) && z, this.streamId, c15111ghZ, min);
this.stream.transportState().onSentBytes(min);
i -= min;
} catch (IOException e) {
throw new RuntimeException(e);
}
} while (i > 0);
}
final void enqueue(C15111ghZ c15111ghZ, int i, boolean z) {
this.pendingWriteBuffer.write(c15111ghZ, i);
this.pendingBufferHasEndOfStream |= z;
}
final boolean hasPendingData() {
return this.pendingWriteBuffer.c > 0;
}
final int streamableBytes() {
return Math.max(0, Math.min(this.window, (int) this.pendingWriteBuffer.c));
}
final int window() {
return this.window;
}
final void clearAllocatedBytes() {
this.allocatedBytes = 0;
}
final int allocatedBytes() {
return this.allocatedBytes;
}
final void allocateBytes(int i) {
this.allocatedBytes += i;
}
}
}