package io.netty.channel;

import g.a.a.a.a;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufHolder;
import io.netty.buffer.Unpooled;
import io.netty.util.Recycler;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.FastThreadLocal;
import io.netty.util.internal.InternalThreadLocalMap;
import io.netty.util.internal.PromiseNotificationUtil;
import io.netty.util.internal.SystemPropertyUtil;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;

/* JADX INFO: loaded from: classes.dex */
public final class ChannelOutboundBuffer {
    public static final /* synthetic */ boolean $assertionsDisabled = false;
    private final Channel channel;
    private volatile Runnable fireChannelWritabilityChangedTask;
    private int flushed;
    private Entry flushedEntry;
    private boolean inFail;
    private int nioBufferCount;
    private long nioBufferSize;
    private Entry tailEntry;
    private volatile long totalPendingSize;
    private Entry unflushedEntry;
    private volatile int unwritable;
    public static final int CHANNEL_OUTBOUND_BUFFER_ENTRY_OVERHEAD = SystemPropertyUtil.getInt("io.netty.transport.outboundBufferEntrySizeOverhead", 96);
    private static final InternalLogger logger = InternalLoggerFactory.getInstance((Class<?>) ChannelOutboundBuffer.class);
    private static final FastThreadLocal<ByteBuffer[]> NIO_BUFFERS = new FastThreadLocal<ByteBuffer[]>() { // from class: io.netty.channel.ChannelOutboundBuffer.1
        @Override // io.netty.util.concurrent.FastThreadLocal
        public ByteBuffer[] initialValue() {
            return new ByteBuffer[1024];
        }
    };
    private static final AtomicLongFieldUpdater<ChannelOutboundBuffer> TOTAL_PENDING_SIZE_UPDATER = AtomicLongFieldUpdater.newUpdater(ChannelOutboundBuffer.class, "totalPendingSize");
    private static final AtomicIntegerFieldUpdater<ChannelOutboundBuffer> UNWRITABLE_UPDATER = AtomicIntegerFieldUpdater.newUpdater(ChannelOutboundBuffer.class, "unwritable");

    public static final class Entry {
        private static final Recycler<Entry> RECYCLER = new Recycler<Entry>() { // from class: io.netty.channel.ChannelOutboundBuffer.Entry.1
            /* JADX WARN: Can't rename method to resolve collision */
            @Override // io.netty.util.Recycler
            public Entry newObject(Recycler.Handle<Entry> handle) {
                return new Entry(handle);
            }
        };
        public ByteBuffer buf;
        public ByteBuffer[] bufs;
        public boolean cancelled;
        public int count;
        private final Recycler.Handle<Entry> handle;
        public Object msg;
        public Entry next;
        public int pendingSize;
        public long progress;
        public ChannelPromise promise;
        public long total;

        private Entry(Recycler.Handle<Entry> handle) {
            this.count = -1;
            this.handle = handle;
        }

        public static Entry newInstance(Object obj, int i2, long j2, ChannelPromise channelPromise) {
            Entry entry = RECYCLER.get();
            entry.msg = obj;
            entry.pendingSize = i2 + ChannelOutboundBuffer.CHANNEL_OUTBOUND_BUFFER_ENTRY_OVERHEAD;
            entry.total = j2;
            entry.promise = channelPromise;
            return entry;
        }

        public int cancel() {
            if (this.cancelled) {
                return 0;
            }
            this.cancelled = true;
            int i2 = this.pendingSize;
            ReferenceCountUtil.safeRelease(this.msg);
            this.msg = Unpooled.EMPTY_BUFFER;
            this.pendingSize = 0;
            this.total = 0L;
            this.progress = 0L;
            this.bufs = null;
            this.buf = null;
            return i2;
        }

        public void recycle() {
            this.next = null;
            this.bufs = null;
            this.buf = null;
            this.msg = null;
            this.promise = null;
            this.progress = 0L;
            this.total = 0L;
            this.pendingSize = 0;
            this.count = -1;
            this.cancelled = false;
            this.handle.recycle(this);
        }

        public Entry recycleAndGetNext() {
            Entry entry = this.next;
            recycle();
            return entry;
        }
    }

    public interface MessageProcessor {
        boolean processMessage(Object obj);
    }

    public ChannelOutboundBuffer(AbstractChannel abstractChannel) {
        this.channel = abstractChannel;
    }

    private void clearNioBuffers() {
        int i2 = this.nioBufferCount;
        if (i2 > 0) {
            this.nioBufferCount = 0;
            Arrays.fill(NIO_BUFFERS.get(), 0, i2, (Object) null);
        }
    }

    private void clearUserDefinedWritability(int i2) {
        int i3;
        int i4;
        int iWritabilityMask = writabilityMask(i2);
        do {
            i3 = this.unwritable;
            i4 = i3 | iWritabilityMask;
        } while (!UNWRITABLE_UPDATER.compareAndSet(this, i3, i4));
        if (i3 != 0 || i4 == 0) {
            return;
        }
        fireChannelWritabilityChanged(true);
    }

    private void decrementPendingOutboundBytes(long j2, boolean z2, boolean z3) {
        if (j2 == 0) {
            return;
        }
        long jAddAndGet = TOTAL_PENDING_SIZE_UPDATER.addAndGet(this, -j2);
        if (!z3 || jAddAndGet >= this.channel.config().getWriteBufferLowWaterMark()) {
            return;
        }
        setWritable(z2);
    }

    private static ByteBuffer[] expandNioBufferArray(ByteBuffer[] byteBufferArr, int i2, int i3) {
        int length = byteBufferArr.length;
        do {
            length <<= 1;
            if (length < 0) {
                throw new IllegalStateException();
            }
        } while (i2 > length);
        ByteBuffer[] byteBufferArr2 = new ByteBuffer[length];
        System.arraycopy(byteBufferArr, 0, byteBufferArr2, 0, i3);
        return byteBufferArr2;
    }

    private void fireChannelWritabilityChanged(boolean z2) {
        final ChannelPipeline channelPipelinePipeline = this.channel.pipeline();
        if (!z2) {
            channelPipelinePipeline.fireChannelWritabilityChanged();
            return;
        }
        Runnable runnable = this.fireChannelWritabilityChangedTask;
        if (runnable == null) {
            runnable = new Runnable() { // from class: io.netty.channel.ChannelOutboundBuffer.2
                @Override // java.lang.Runnable
                public void run() {
                    channelPipelinePipeline.fireChannelWritabilityChanged();
                }
            };
            this.fireChannelWritabilityChangedTask = runnable;
        }
        this.channel.eventLoop().execute(runnable);
    }

    private void incrementPendingOutboundBytes(long j2, boolean z2) {
        if (j2 != 0 && TOTAL_PENDING_SIZE_UPDATER.addAndGet(this, j2) > this.channel.config().getWriteBufferHighWaterMark()) {
            setUnwritable(z2);
        }
    }

    private boolean isFlushedEntry(Entry entry) {
        return (entry == null || entry == this.unflushedEntry) ? false : true;
    }

    private boolean remove0(Throwable th, boolean z2) {
        Entry entry = this.flushedEntry;
        if (entry == null) {
            clearNioBuffers();
            return false;
        }
        Object obj = entry.msg;
        ChannelPromise channelPromise = entry.promise;
        int i2 = entry.pendingSize;
        removeEntry(entry);
        if (!entry.cancelled) {
            ReferenceCountUtil.safeRelease(obj);
            safeFail(channelPromise, th);
            decrementPendingOutboundBytes(i2, false, z2);
        }
        entry.recycle();
        return true;
    }

    private void removeEntry(Entry entry) {
        int i2 = this.flushed - 1;
        this.flushed = i2;
        if (i2 != 0) {
            this.flushedEntry = entry.next;
            return;
        }
        this.flushedEntry = null;
        if (entry == this.tailEntry) {
            this.tailEntry = null;
            this.unflushedEntry = null;
        }
    }

    private static void safeFail(ChannelPromise channelPromise, Throwable th) {
        PromiseNotificationUtil.tryFailure(channelPromise, th, channelPromise instanceof VoidChannelPromise ? null : logger);
    }

    private static void safeSuccess(ChannelPromise channelPromise) {
        PromiseNotificationUtil.trySuccess(channelPromise, null, channelPromise instanceof VoidChannelPromise ? null : logger);
    }

    private void setUnwritable(boolean z2) {
        int i2;
        int i3;
        do {
            i2 = this.unwritable;
            i3 = i2 | 1;
        } while (!UNWRITABLE_UPDATER.compareAndSet(this, i2, i3));
        if (i2 != 0 || i3 == 0) {
            return;
        }
        fireChannelWritabilityChanged(z2);
    }

    private void setUserDefinedWritability(int i2) {
        int i3;
        int i4;
        int i5 = ~writabilityMask(i2);
        do {
            i3 = this.unwritable;
            i4 = i3 & i5;
        } while (!UNWRITABLE_UPDATER.compareAndSet(this, i3, i4));
        if (i3 == 0 || i4 != 0) {
            return;
        }
        fireChannelWritabilityChanged(true);
    }

    private void setWritable(boolean z2) {
        int i2;
        int i3;
        do {
            i2 = this.unwritable;
            i3 = i2 & (-2);
        } while (!UNWRITABLE_UPDATER.compareAndSet(this, i2, i3));
        if (i2 == 0 || i3 != 0) {
            return;
        }
        fireChannelWritabilityChanged(z2);
    }

    private static long total(Object obj) {
        if (obj instanceof ByteBuf) {
            return ((ByteBuf) obj).readableBytes();
        }
        if (obj instanceof FileRegion) {
            return ((FileRegion) obj).count();
        }
        if (obj instanceof ByteBufHolder) {
            return ((ByteBufHolder) obj).content().readableBytes();
        }
        return -1L;
    }

    private static int writabilityMask(int i2) {
        if (i2 < 1 || i2 > 31) {
            throw new IllegalArgumentException(a.n("index: ", i2, " (expected: 1~31)"));
        }
        return 1 << i2;
    }

    public void addFlush() {
        Entry entry = this.unflushedEntry;
        if (entry != null) {
            if (this.flushedEntry == null) {
                this.flushedEntry = entry;
            }
            do {
                this.flushed++;
                if (!entry.promise.setUncancellable()) {
                    decrementPendingOutboundBytes(entry.cancel(), false, true);
                }
                entry = entry.next;
            } while (entry != null);
            this.unflushedEntry = null;
        }
    }

    public void addMessage(Object obj, int i2, ChannelPromise channelPromise) {
        Entry entryNewInstance = Entry.newInstance(obj, i2, total(obj), channelPromise);
        Entry entry = this.tailEntry;
        if (entry == null) {
            this.flushedEntry = null;
        } else {
            entry.next = entryNewInstance;
        }
        this.tailEntry = entryNewInstance;
        if (this.unflushedEntry == null) {
            this.unflushedEntry = entryNewInstance;
        }
        incrementPendingOutboundBytes(entryNewInstance.pendingSize, false);
    }

    public long bytesBeforeUnwritable() {
        long writeBufferHighWaterMark = ((long) this.channel.config().getWriteBufferHighWaterMark()) - this.totalPendingSize;
        if (writeBufferHighWaterMark <= 0 || !isWritable()) {
            return 0L;
        }
        return writeBufferHighWaterMark;
    }

    public long bytesBeforeWritable() {
        long writeBufferLowWaterMark = this.totalPendingSize - ((long) this.channel.config().getWriteBufferLowWaterMark());
        if (writeBufferLowWaterMark <= 0 || isWritable()) {
            return 0L;
        }
        return writeBufferLowWaterMark;
    }

    public void close(final Throwable th, final boolean z2) {
        if (this.inFail) {
            this.channel.eventLoop().execute(new Runnable() { // from class: io.netty.channel.ChannelOutboundBuffer.3
                @Override // java.lang.Runnable
                public void run() {
                    ChannelOutboundBuffer.this.close(th, z2);
                }
            });
            return;
        }
        this.inFail = true;
        if (!z2 && this.channel.isOpen()) {
            throw new IllegalStateException("close() must be invoked after the channel is closed.");
        }
        if (!isEmpty()) {
            throw new IllegalStateException("close() must be invoked after all flushed writes are handled.");
        }
        try {
            for (Entry entryRecycleAndGetNext = this.unflushedEntry; entryRecycleAndGetNext != null; entryRecycleAndGetNext = entryRecycleAndGetNext.recycleAndGetNext()) {
                TOTAL_PENDING_SIZE_UPDATER.addAndGet(this, -entryRecycleAndGetNext.pendingSize);
                if (!entryRecycleAndGetNext.cancelled) {
                    ReferenceCountUtil.safeRelease(entryRecycleAndGetNext.msg);
                    safeFail(entryRecycleAndGetNext.promise, th);
                }
            }
            this.inFail = false;
            clearNioBuffers();
        } catch (Throwable th2) {
            this.inFail = false;
            throw th2;
        }
    }

    public void close(ClosedChannelException closedChannelException) {
        close(closedChannelException, false);
    }

    public Object current() {
        Entry entry = this.flushedEntry;
        if (entry == null) {
            return null;
        }
        return entry.msg;
    }

    public void decrementPendingOutboundBytes(long j2) {
        decrementPendingOutboundBytes(j2, true, true);
    }

    public void failFlushed(Throwable th, boolean z2) {
        if (this.inFail) {
            return;
        }
        try {
            this.inFail = true;
            do {
            } while (remove0(th, z2));
        } finally {
            this.inFail = false;
        }
    }

    public void forEachFlushedMessage(MessageProcessor messageProcessor) {
        Objects.requireNonNull(messageProcessor, "processor");
        Entry entry = this.flushedEntry;
        if (entry == null) {
            return;
        }
        do {
            if (!entry.cancelled && !messageProcessor.processMessage(entry.msg)) {
                return;
            } else {
                entry = entry.next;
            }
        } while (isFlushedEntry(entry));
    }

    public boolean getUserDefinedWritability(int i2) {
        return (writabilityMask(i2) & this.unwritable) == 0;
    }

    public void incrementPendingOutboundBytes(long j2) {
        incrementPendingOutboundBytes(j2, true);
    }

    public boolean isEmpty() {
        return this.flushed == 0;
    }

    public boolean isWritable() {
        return this.unwritable == 0;
    }

    public int nioBufferCount() {
        return this.nioBufferCount;
    }

    public long nioBufferSize() {
        return this.nioBufferSize;
    }

    public ByteBuffer[] nioBuffers() {
        return nioBuffers(Integer.MAX_VALUE, 2147483647L);
    }

    public ByteBuffer[] nioBuffers(int i2, long j2) {
        ByteBuf byteBuf;
        int i3;
        int iWriterIndex;
        ByteBuffer byteBuffer;
        long j3 = 0;
        InternalThreadLocalMap internalThreadLocalMap = InternalThreadLocalMap.get();
        ByteBuffer[] byteBufferArrExpandNioBufferArray = NIO_BUFFERS.get(internalThreadLocalMap);
        int i4 = 0;
        for (Entry entry = this.flushedEntry; isFlushedEntry(entry); entry = entry.next) {
            Object obj = entry.msg;
            if (!(obj instanceof ByteBuf)) {
                break;
            }
            if (!entry.cancelled && (iWriterIndex = byteBuf.writerIndex() - (i3 = (byteBuf = (ByteBuf) obj).readerIndex())) > 0) {
                long j4 = iWriterIndex;
                if (j2 - j4 < j3 && i4 != 0) {
                    break;
                }
                j3 += j4;
                int iNioBufferCount = entry.count;
                if (iNioBufferCount == -1) {
                    iNioBufferCount = byteBuf.nioBufferCount();
                    entry.count = iNioBufferCount;
                }
                int iMin = Math.min(i2, i4 + iNioBufferCount);
                if (iMin > byteBufferArrExpandNioBufferArray.length) {
                    byteBufferArrExpandNioBufferArray = expandNioBufferArray(byteBufferArrExpandNioBufferArray, iMin, i4);
                    NIO_BUFFERS.set(internalThreadLocalMap, byteBufferArrExpandNioBufferArray);
                }
                if (iNioBufferCount == 1) {
                    ByteBuffer byteBufferInternalNioBuffer = entry.buf;
                    if (byteBufferInternalNioBuffer == null) {
                        byteBufferInternalNioBuffer = byteBuf.internalNioBuffer(i3, iWriterIndex);
                        entry.buf = byteBufferInternalNioBuffer;
                    }
                    byteBufferArrExpandNioBufferArray[i4] = byteBufferInternalNioBuffer;
                    i4++;
                } else {
                    ByteBuffer[] byteBufferArrNioBuffers = entry.bufs;
                    if (byteBufferArrNioBuffers == null) {
                        byteBufferArrNioBuffers = byteBuf.nioBuffers();
                        entry.bufs = byteBufferArrNioBuffers;
                    }
                    for (int i5 = 0; i5 < byteBufferArrNioBuffers.length && i4 < i2 && (byteBuffer = byteBufferArrNioBuffers[i5]) != null; i5++) {
                        if (byteBuffer.hasRemaining()) {
                            byteBufferArrExpandNioBufferArray[i4] = byteBuffer;
                            i4++;
                        }
                    }
                }
                if (i4 == i2) {
                    break;
                }
            }
        }
        this.nioBufferCount = i4;
        this.nioBufferSize = j3;
        return byteBufferArrExpandNioBufferArray;
    }

    public void progress(long j2) {
        Entry entry = this.flushedEntry;
        ChannelPromise channelPromise = entry.promise;
        if (channelPromise instanceof ChannelProgressivePromise) {
            long j3 = entry.progress + j2;
            entry.progress = j3;
            ((ChannelProgressivePromise) channelPromise).tryProgress(j3, entry.total);
        }
    }

    @Deprecated
    public void recycle() {
    }

    public boolean remove() {
        Entry entry = this.flushedEntry;
        if (entry == null) {
            clearNioBuffers();
            return false;
        }
        Object obj = entry.msg;
        ChannelPromise channelPromise = entry.promise;
        int i2 = entry.pendingSize;
        removeEntry(entry);
        if (!entry.cancelled) {
            ReferenceCountUtil.safeRelease(obj);
            safeSuccess(channelPromise);
            decrementPendingOutboundBytes(i2, false, true);
        }
        entry.recycle();
        return true;
    }

    public boolean remove(Throwable th) {
        return remove0(th, true);
    }

    public void removeBytes(long j2) {
        while (true) {
            Object objCurrent = current();
            if (!(objCurrent instanceof ByteBuf)) {
                break;
            }
            ByteBuf byteBuf = (ByteBuf) objCurrent;
            int i2 = byteBuf.readerIndex();
            long jWriterIndex = byteBuf.writerIndex() - i2;
            if (jWriterIndex <= j2) {
                if (j2 != 0) {
                    progress(jWriterIndex);
                    j2 -= jWriterIndex;
                }
                remove();
            } else if (j2 != 0) {
                byteBuf.readerIndex(i2 + ((int) j2));
                progress(j2);
            }
        }
        clearNioBuffers();
    }

    public void setUserDefinedWritability(int i2, boolean z2) {
        if (z2) {
            setUserDefinedWritability(i2);
        } else {
            clearUserDefinedWritability(i2);
        }
    }

    public int size() {
        return this.flushed;
    }

    public long totalPendingWriteBytes() {
        return this.totalPendingSize;
    }
}
