[/
 / Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 /
 / Distributed under the Boost Software License, Version 1.0. (See accompanying
 / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 /]

[section:implementation Platform-Specific Implementation Notes]

This section lists platform-specific implementation details, such as the
default demultiplexing mechanism, the number of threads created internally, and
when threads are created.


[heading Linux Kernel 2.4]

Demultiplexing mechanism:

* Uses `select` for demultiplexing. This means that the number of file
descriptors in the process cannot be permitted to exceed `FD_SETSIZE`.

Threads:

* Demultiplexing using `select` is performed in one of the threads that calls
`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
`io_context::poll_one()`.

* An additional thread per `io_context` is used to emulate asynchronous host
resolution. This thread is created on the first call to either
`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.

Scatter-Gather:

* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.


[heading Linux Kernel 2.6]

Demultiplexing mechanism:

* Uses `epoll` for demultiplexing.

Threads:

* Demultiplexing using `epoll` is performed in one of the threads that calls
`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
`io_context::poll_one()`.

* An additional thread per `io_context` is used to emulate asynchronous host
resolution. This thread is created on the first call to either
`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.

Scatter-Gather:

* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.


[heading Linux Kernel 5.10]

Demultiplexing mechanism:

* If `ASIO_HAS_IO_URING` is defined, uses `io_uring` for file-related
asynchonous operations.

* Uses `epoll` for demultiplexing other event sources.

* Optionally uses `io_uring` for all asynchronous operations if, in addition
to `ASIO_HAS_IO_URING`, `ASIO_DISABLE_EPOLL` is defined to disable `epoll`.

Threads:

* Demultiplexing using `epoll` and `io_uring` is performed in one of the threads
that calls `io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
`io_context::poll_one()`.

* An additional thread per `io_context` is used to emulate asynchronous host
resolution. This thread is created on the first call to either
`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.

Scatter-Gather:

* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.


[heading Solaris]

Demultiplexing mechanism:

* Uses [^/dev/poll] for demultiplexing.

Threads:

* Demultiplexing using [^/dev/poll] is performed in one of the threads that
calls `io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
`io_context::poll_one()`.

* An additional thread per `io_context` is used to emulate asynchronous host
resolution. This thread is created on the first call to either
`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.

Scatter-Gather:

* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.


[heading QNX Neutrino]

Demultiplexing mechanism:

* Uses `select` for demultiplexing. This means that the number of file
descriptors in the process cannot be permitted to exceed `FD_SETSIZE`.

Threads:

* Demultiplexing using `select` is performed in one of the threads that calls
`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
`io_context::poll_one()`.

* An additional thread per `io_context` is used to emulate asynchronous host
resolution. This thread is created on the first call to either
`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.

Scatter-Gather:

* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.


[heading Mac OS X]

Demultiplexing mechanism:

* Uses `kqueue` for demultiplexing.

Threads:

* Demultiplexing using `kqueue` is performed in one of the threads that calls
`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
`io_context::poll_one()`.

* An additional thread per `io_context` is used to emulate asynchronous host
resolution. This thread is created on the first call to either
`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.

Scatter-Gather:

* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.


[heading FreeBSD]

Demultiplexing mechanism:

* Uses `kqueue` for demultiplexing.

Threads:

* Demultiplexing using `kqueue` is performed in one of the threads that calls
`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
`io_context::poll_one()`.

* An additional thread per `io_context` is used to emulate asynchronous host
resolution. This thread is created on the first call to either
`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.

Scatter-Gather:

* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.


[heading AIX]

Demultiplexing mechanism:

* Uses `select` for demultiplexing. This means that the number of file
descriptors in the process cannot be permitted to exceed `FD_SETSIZE`.

Threads:

* Demultiplexing using `select` is performed in one of the threads that calls
`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
`io_context::poll_one()`.

* An additional thread per `io_context` is used to emulate asynchronous host
resolution. This thread is created on the first call to either
`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.

Scatter-Gather:

* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.


[heading HP-UX]

Demultiplexing mechanism:

* Uses `select` for demultiplexing. This means that the number of file
descriptors in the process cannot be permitted to exceed `FD_SETSIZE`.

Threads:

* Demultiplexing using `select` is performed in one of the threads that calls
`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
`io_context::poll_one()`.

* An additional thread per `io_context` is used to emulate asynchronous host
resolution. This thread is created on the first call to either
`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.

Scatter-Gather:

* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.


[heading Tru64]

Demultiplexing mechanism:

* Uses `select` for demultiplexing. This means that the number of file
descriptors in the process cannot be permitted to exceed `FD_SETSIZE`.

Threads:

* Demultiplexing using `select` is performed in one of the threads that calls
`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
`io_context::poll_one()`.

* An additional thread per `io_context` is used to emulate asynchronous host
resolution. This thread is created on the first call to either
`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.

Scatter-Gather:

* At most `min(64,IOV_MAX)` buffers may be transferred in a single operation.


[heading Windows 95, 98 and Me]

Demultiplexing mechanism:

* Uses `select` for demultiplexing.

Threads:

* Demultiplexing using `select` is performed in one of the threads that calls
`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
`io_context::poll_one()`.

* An additional thread per `io_context` is used to emulate asynchronous host
resolution. This thread is created on the first call to either
`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.

Scatter-Gather:

* For sockets, at most 16 buffers may be transferred in a single operation.


[heading Windows NT, 2000, XP, 2003, Vista, 7, 8, 10 and 11]

Demultiplexing mechanism:

* Uses overlapped I/O and I/O completion ports for all asynchronous socket
operations except for asynchronous connect.

* Uses `select` for emulating asynchronous connect.

Threads:

* Demultiplexing using I/O completion ports is performed in all threads that call
`io_context::run()`, `io_context::run_one()`, `io_context::poll()` or
`io_context::poll_one()`.

* An additional thread per `io_context` is used to trigger timers. This thread
is created on construction of the first `basic_deadline_timer` or
`basic_waitable_timer` objects.

* An additional thread per `io_context` may be used for `select`
  demultiplexing. This thread is created on the first call to:

  * A socket `async_wait()` function, except when using `wait_read` on
    a stream-oriented socket. (For `wait_read` on a stream-oriented socket,
    the overlapped I/O operation `WSARecv` is used and no additional thread
    is required.)

  * A socket `async_connect()` operation, if the overlapped I/O
    operation `ConnectEx` is unavailable. (On recent versions of Windows,
    `ConnectEx` is used and no additional thread is required.)

* An additional thread per `io_context` is used to emulate asynchronous host
resolution. This thread is created on the first call to either
`ip::tcp::resolver::async_resolve()` or `ip::udp::resolver::async_resolve()`.

Scatter-Gather:

* For sockets, at most 64 buffers may be transferred in a single operation.

* For stream-oriented handles, only one buffer may be transferred in a single
operation.

[heading Windows Runtime]

Asio provides limited support for the Windows Runtime. It requires that the
language extensions be enabled. Due to the restricted facilities exposed by the
Windows Runtime API, the support comes with the following caveats:

* The core facilities such as the `io_context`, `strand`, buffers, composed
  operations, timers, etc., should all work as normal.

* For sockets, only client-side TCP is supported.

* Explicit binding of a client-side TCP socket is not supported.

* The `cancel()` function is not supported for sockets. Asynchronous
  operations may only be cancelled by closing the socket.

* Operations that use `null_buffers` are not supported.

* Only `tcp::no_delay` and `socket_base::keep_alive` options are supported.

* Resolvers do not support service names, only numbers. I.e. you must
  use "80" rather than "http".

* Most resolver query flags have no effect.

Demultiplexing mechanism:

* Uses the `Windows::Networking::Sockets::StreamSocket` class to implement
  asynchronous TCP socket operations.

Threads:

* Event completions are delivered to the Windows thread pool and posted to the
  `io_context` for the handler to be executed.

* An additional thread per `io_context` is used to trigger timers. This thread
  is created on construction of the first timer objects.

Scatter-Gather:

* For sockets, at most one buffer may be transferred in a single operation.


[endsect]
