Hi swift-corelibs-dev,
I recently found myself with a DispatchData and wanted to use writev(2). So
what I need was basically an array of pointers and lengths, not necessarily
contiguous. That's exactly what DispatchData is so I thought it should be quite
straightforward.
Obviously I need a guarantee that the pointers to the storage of all the
DispatchData 'chunks' are all valid until writev returns.
I first checked the C API because it's documented and dispatch_data_apply seems
to give me the guarantees that I need:
<quote source="man dispatch_data_apply">
The dispatch_data_apply() function provides read access to represented
memory without requiring it to be mapped as a
single contiguous region. It traverses the memory regions represented by
the data argument in logical order, invokes
the specified applier block for each region and returns a boolean
indicating whether traversal completed success-
fully. The applier block is passed the following arguments for each memory
region and returns a boolean indicating
whether traversal should continue:
dispatch_data_t rgn data object representing the region
size_t offset logical position of the region in data
const void *loc memory location of the region
size_t size extent of the region
The rgn data object is released by the system when the applier block
returns. The associated memory location loc is
valid only as long as rgn has not been deallocated; if loc is needed
outside of the applier block, the rgn object
must be retained in the block.
</quote>
Ie. to guarantee that all the `loc`s I get are still valid, I just need to make
sure that all the `rgn`s I get are retained until writev returns. Easy!
Now I wanted to switch to Swift and unfortunately saw that
DispatchData.enumerateBytes doesn't give me access to the region so I can't
retain it :(.
So how can I achieve that, is it guaranteed that it's good enough to retain the
overall DispatchData? Or in code, is this guaranteed to be correct?
extension DispatchData {
func writeVector(fileDescriptor: Int32) -> ssize_t {
var iobufs: [iovec] = []
self.enumerateBytes { (buf, _, _) in
var iobuf = iovec()
iobuf.iov_base = UnsafeMutableRawPointer(mutating: buf.baseAddress!)
iobuf.iov_len = buf.count
iobufs.append(iobuf)
}
return writev(fileDescriptor, iobufs, Int32(iobufs.count))
}
}
Many thanks,
Johannes
_______________________________________________
swift-corelibs-dev mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-corelibs-dev