[PITCH] io_uring support in Swift System on Linux

IORingSwift has been around for a couple of years now ;) We're using it in our embedded audio product for UART, SPI and I2C as well as socket and file I/O.

Public API provides structured concurrency wrappers around common operations such as reading and writing. Multishot APIs, such as accept(2), which can return multiple completions over time return an AnyAsyncSequence. Internally, wrappers allocate a concrete instance of Submission<T>, representing an initialized Submission Queue Entry (SQE), which is then submitted to the io_uring. Completion handlers are handled by having libdispatch monitor an eventfd(2) representing available completions. The user_data in each queue entry is a block, which executes the onCompletion(cqe:) method of the Submission<T> instance in the ring's isolated context.

let clients: AnyAsyncSequence<Socket> = try await socket.accept()
for try await client in clients {
    Task {
        repeat {
            let data = try await client.receive(count: bufferSize)
            try await client.send(data)
        } while true
    }
}

Plenty of other examples here. Original discussion here.

Things I would do differently? The use of classes does cause a lot of allocations (although this hasn't been a bottleneck for us). And, SE-0461 will make it easier to avoid the global actor.

5 Likes