[WIP] Refactor to use dispatch_io for tasks, and wait for EOF

Hopefully resolves #151, #139, and #135.

/cc @joshaber @keithduncan
`dispatch_io_close` doesn’t cancel the source and clean up, it stops accepting new I/O requests (delivering ECANCELED to any that are enqueued) and when any extant requests have completed (these are interruptible with the STOP option) it schedules the `cleanupHandler` on the queue given at init time