I am creating DispatchIO channels using the file descriptor constructor:
self.channel = DispatchIO(type: .random, fileDescriptor: self.file, queue: fileProcessingQueue, cleanupHandler: { (errorCode) in
// clean up when the channel closes
})
The documentation for cleanupHandler states:
"The handler to execute once the channel is closed."
The better documentation (when you switch language to ObjC) states:
"The block to enqueue when the system relinquishes control of the channel’s file descriptor."
"... the system takes control of the specified file descriptor until one of the following occurs:
You close the channel by calling the
dispatch_io_close
function.
..."
So from both of these, I expect the handler gets enqueued and executed if I call
self.channel.close(flags [.stop])
But it seems to never get executed under this condition. In fact, it's very difficult to get the cleanup handler to be called at all. The only way so far I have been able to get it to execute is by calling close() on the underlying file descriptor. Am I doing something wrong here? There's cleanup that I want to do when the channel closes that is different than the cleanup I want to do when I'm done with the file descriptor. Is this not the correct place to do it?
I’m not entirely sure what’s going in your situation but my experience is that
DispatchIO
works pretty well. Pasted is below is an example that simply streams through a file.
I’ll second john daniel’s recommendation that you read the doc comments in the headers. You should also avail yourself of the various man pages, starting with the
dispatch_io_create
man page.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
import Foundation
func main() {
let io = DispatchIO(type: .stream, path: "/Users/quinn/Yo Ho Ho.dmg", oflag: O_RDONLY, mode: 0o666, queue: .main, cleanupHandler: { err in
print("clean up, err: \(err)")
})!
func startRead() {
io.read(offset: 0, length: 65536, queue: .main) { (done, dataQ, err) in
let data = dataQ ?? DispatchData.empty
if data.count != 0 {
print("read, count: \(data.count)")
} else {
print("EOF")
io.close(flags: [])
return
}
if err != 0 {
print("failed, err: \(err)")
io.close(flags: [.stop])
return
}
if done {
startRead()
}
}
}
startRead()
dispatchMain()
}
main()
exit(EXIT_SUCCESS)