Preliminary. ThinkMeta ConcurrentTasks and this documentation are preliminary; everything is subject to change.

Asynchronous I/O

File and socket operations in ConcurrentTasks are overlapped Windows I/O on the core's I/O completion port. A task starts an operation and is suspended; when the operation completes, the core's I/O thread resumes it. No thread blocks in between.

Enabling asynchronous I/O

AsyncIo::EnableAsyncIo creates the completion port and the I/O thread that drains it; AsyncIo::DisableAsyncIo takes it back. The calls are counted, so a library and the application can both enable it.

Important

Enable asynchronous I/O before you create files or sockets, and disable it only when no operation is pending any more.

How an operation runs

  1. A file or socket is opened for overlapped I/O and associated with the port (AssociateHandleWithIoCompletionPort). AsyncFile and AsyncSocket do this in their Create.
  2. Each operation carries a request object that owns the OVERLAPPED (AsyncIoRequestBase). The Win32 call is started with it.
  3. When the operation completes, the I/O thread passes the result to the request (RequestCompleted). A waitable request sets an event, which resumes the waiting task.
  4. If the operation completes at once, the request is completed on the calling thread and no completion packet follows.

Waiting and starting forms

The library offers each operation in two forms:

On top of that, AsyncFile::ReadFile and WriteFile move a whole file through a sequential memory with several requests in flight, and StreamedFileReader and OrderedFileWriter stream large files with bounded memory.

Important

A request and its buffer must stay alive and in place until the operation has completed. Close or destroy a file or socket only when no operation on it is pending.

Errors

File operations return Win32 error codes (ErrorCode; ERROR_SUCCESS on success), socket operations Winsock codes (WinsockErrorCode). The starting forms may also return the "pending" code of their API.

See also