Driving writev(2) with a list of Data


(Johannes Weiss) #1

Hi swift-corelibs-dev,

Similar to my question "driving writev(2) from DispatchData" [1] (much appreciated if someone had an answer for that), today I'd like to know if there's a better way to drive writev(2) [2] from a list of Data.

Sure, I can get the pointers to the individual Data using someData.withUnsafeBytes {} but that only gives me one pointer, for writev, I'll need them all to call writev. The only way without violating the contract of withUnsafeBytes {} I could come up with is using recursion which is obviously not great :\.

Here my untested demo implementation using recursion to show what I mean:

--- SNIP ---
func dataListWriteV(fileDescriptor: Int32, datas: [Data]) -> Int {
    let maxRecursionDepth = 32
    var datas = datas
    var allPointers: [UnsafeBufferPointer<UInt8>] = []
    func dataListWriteV_(datas: inout [Data], myIndex: Int) -> Int {
        let myData: Data = datas[myIndex]
        return myData.withUnsafeBytes { (myPtr: UnsafePointer<UInt8>) -> Int in
            allPointers.append(UnsafeBufferPointer(start: myPtr, count: myData.count))
            if myIndex + 1 >= datas.count || myIndex > maxRecursionDepth {
                var iovecs = allPointers.map { iovec(iov_base: UnsafeMutableRawPointer(mutating: $0.baseAddress),
                                                     iov_len: $0.count) }
                return writev(fileDescriptor, &iovecs, Int32(iovecs.count))
            } else {
                return dataListWriteV_(datas: &datas, myIndex: myIndex+1)
            }
        }
    }
    return dataListWriteV_(datas: &datas, myIndex: 0)
}
--- SNAP ---

[1]: https://www.mail-archive.com/swift-corelibs-dev@swift.org/msg00930.html
[2]: https://linux.die.net/man/2/writev

···

--
  Johannes