Use a single IO thread when downloading S3 objects

We have seen issues on some OSes that have trouble with
concurrent IO threads to different parts of the same file.
Despite these being non overlapping parts of the file, this
doesn't always work.

The fix is to switch to a single IO thread. All other threads are
now passed an IO queue in which they can submit either `IORequests`
or `IOCompleteRequests` that the IO thread understands.