### 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.

##### 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.

##### 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.

##### 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.

##### 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.

##### 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.

##### 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.

##### 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.

##### 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.

##### 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.

##### 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.

##### 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.

##### 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.

##### 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.