Repository: apple/swift-nio
File: Sources/NIOPosix/BaseStreamSocketChannel.swift (Swift)

Code before:
            scalarFileWriteOperation: { descriptor, index, endIndex in
                try self.socket.sendFile(fd: descriptor, offset: index, count: endIndex - index)
            }
        )
        return result
    }

    final override func close0(error: Error, mode: CloseMode, promise: EventLoopPromise<Void>?) {
        do {
            switch mode {
            case .output:
                if self.outputShutdown {
                    promise?.fail(ChannelError._outputClosed)
                    return
                }
                if self.inputShutdown {
                    // Escalate to full closure
                    self.close0(error: error, mode: .all, promise: promise)
                    return
                }
                self.unregisterForWritable()

                let outboundCloseState = self.pendingWrites.close(promise)
                switch outboundCloseState {
                case .open:
                    preconditionFailure("Close resulted in an open state, this should never happen")
                case .pending:
                    ()  // nothing to do
                case .readyForClose(let closePromise):
                    assert(promise == closePromise)
                    // Shutdown the socket only when the pending writes are dealt with
                    do {
                        try self.shutdownSocket(mode: mode)
                        closePromise?.succeed(())
                    } catch let err {
                        closePromise?.fail(err)
                    }
                    self.pendingWrites.outboundCloseState = .closed
                case .closed:
                    ()  // nothing to do
                }

                self.pipeline.fireUserInboundEventTriggered(ChannelEvent.outputClosed)
            case .input:
                if self.inputShutdown {
                    promise?.fail(ChannelError._inputClosed)
                    return
                }
                if self.outputShutdown {
                    // Escalate to full closure
                    self.close0(error: error, mode: .all, promise: promise)

Review comment (bug):
Let's avoid this precondition failure. Instead, we should produce an error just before line 219, and go ahead and close outbound anyway. We can then drop this to `assertionFailure` so that it crashes in testing.

Code after:
            scalarFileWriteOperation: { descriptor, index, endIndex in
                try self.socket.sendFile(fd: descriptor, offset: index, count: endIndex - index)
            }
        )
        return result
    }

    final override func close0(error: Error, mode: CloseMode, promise: EventLoopPromise<Void>?) {
        do {
            switch mode {
            case .output:
                if self.outputShutdown {
                    promise?.fail(ChannelError._outputClosed)
                    return
                }
                if self.inputShutdown {
                    // Escalate to full closure
                    self.close0(error: error, mode: .all, promise: promise)
                    return
                }

                let result = self.pendingWrites.closeOutbound(promise)
                switch result {
                case .pending:
                    ()  // promise is stored in `pendingWrites` state for completing later

                case .readyForClose(let closePromise):
                    // Shutdown the socket only when the pending writes are dealt with
                    do {
                        try self.shutdownSocket(mode: mode)
                        closePromise?.succeed(())
                    } catch let err {
                        closePromise?.fail(err)
                    }
                    self.unregisterForWritable()
                    self.pipeline.fireUserInboundEventTriggered(ChannelEvent.outputClosed)

                case .closed(let closePromise):
                    closePromise?.succeed(())

                case .errored(let err, let closePromise):
                    assertionFailure("Close errored: \(err)")
                    closePromise?.fail(err)

                    // Escalate to full closure
                    // promise is nil here because we have used the supplied promise to convey failure of the half-close
                    self.close0(error: err, mode: .all, promise: nil)
                }

            case .input:
                if self.inputShutdown {