Repository: netty/netty
File: transport-classes-io_uring/src/main/java/io/netty/channel/uring/AbstractIoUringChannel.java (Java)

Code before:
            msgHdrMemoryArray.release();
            msgHdrMemoryArray = null;
        }
    }

    @Override
    protected void doClose() throws Exception {
        active = false;

        if (registration != null && registration.isValid()) {
            if (socket.markClosed()) {
                int fd = fd().intValue();
                IoUringIoOps ops = IoUringIoOps.newClose(fd, (byte) 0, nextOpsId());
                registration.submit(ops);

                boolean cancelConnect = false;
                try {
                    ChannelPromise connectPromise = AbstractIoUringChannel.this.connectPromise;
                    if (connectPromise != null) {
                        // Use tryFailure() instead of setFailure() to avoid the race against cancel().
                        connectPromise.tryFailure(new ClosedChannelException());
                        AbstractIoUringChannel.this.connectPromise = null;
                        cancelConnect = true;
                    }

                    cancelConnectTimeoutFuture();
                } finally {
                    // It's important we cancel all outstanding connect, write and read operations now so
                    // we will be able to process a delayed close if needed.
                    ioUringUnsafe().cancelOps(cancelConnect);
                }
            }
        } else {
            // This one was never registered just use a syscall to close.
            socket.close();
            ioUringUnsafe().freeResourcesNowIfNeeded(null);
        }
    }

    @Override
    protected final void doBeginRead() {
        if (inputClosedSeenErrorOnRead) {
            // We did see an error while reading and so closed the input. Stop reading.
            return;
        }
        if (readPending) {
            // We already have a read pending.
            return;
        }
        if (inReadComplete || !isActive()) {
            // We are currently in the readComplete(...) callback which might issue more reads by itself. Just

Review comment (suggestion):
I think we need to do this before we submit the close, since the fd can be reused as soon as close is completed, and then these operations can end up hitting ops for different channels.

Code after:
            msgHdrMemoryArray.release();
            msgHdrMemoryArray = null;
        }
    }

    @Override
    protected void doClose() throws Exception {
        active = false;

        if (registration != null && registration.isValid()) {
            if (socket.markClosed()) {
                boolean cancelConnect = false;
                try {
                    ChannelPromise connectPromise = AbstractIoUringChannel.this.connectPromise;
                    if (connectPromise != null) {
                        // Use tryFailure() instead of setFailure() to avoid the race against cancel().
                        connectPromise.tryFailure(new ClosedChannelException());
                        AbstractIoUringChannel.this.connectPromise = null;
                        cancelConnect = true;
                    }

                    cancelConnectTimeoutFuture();
                } finally {
                    // It's important we cancel all outstanding connect, write and read operations now so
                    // we will be able to process a delayed close if needed.
                    ioUringUnsafe().cancelOps(cancelConnect);
                }

                int fd = fd().intValue();
                IoUringIoOps ops = IoUringIoOps.newClose(fd, (byte) 0, nextOpsId());
                registration.submit(ops);
            }
        } else {
            // This one was never registered just use a syscall to close.
            socket.close();
            ioUringUnsafe().freeResourcesNowIfNeeded(null);
        }
    }

    @Override
    protected final void doBeginRead() {
        if (inputClosedSeenErrorOnRead) {
            // We did see an error while reading and so closed the input. Stop reading.
            return;
        }
        if (readPending) {
            // We already have a read pending.
            return;
        }
        if (inReadComplete || !isActive()) {
            // We are currently in the readComplete(...) callback which might issue more reads by itself. Just