Preview of main at d0a501a, 2026-11-07

webcpp::asio makes Boost-style asynchronous C++ programs usable in WebAssembly: Emscripten for browsers, and WASIp2 or WASIp3 for component runtimes such as Wasmtime. JSPI and Asyncify are separate Emscripten suspension choices. The capability matrix also distinguishes exceptions, threads and runtime prerequisites.

Native equivalents are actual Boost.Asio types. Wasm selects a versioned implementation shipped under WebCPP’s own headers, using the same source contract with B2 or another build system. Use webcpp::asio consistently for contexts, executors, timers, sockets and completion tokens. See How-to: consume the shipped implementation for the compiled runtime sources and dependencies.

In the browser, io_context::run() can suspend into the page’s event loop. Browser events wake it, and a configurable handler-count budget offers the browser opportunities to process other work. A long handler can still block the page. Native and WASI contexts use their target’s reactor instead.

WASIp2 provides single-threaded timers, TCP/UDP, pollable-driven forward DNS, supplied CLI streams and optional source-built TLS. See Build for WASIp2 for its explicit limitations. WASIp3 provides timers, TCP/UDP, waitable-driven forward DNS and the same optional TLS provider, with single-thread and experimental cooperative-thread profiles. See Target and variant capabilities for their limits and the features available in each target variant.

The separate Cobalt library uses this executor and operation model for coroutine applications. Its compiled core, runner and optional SSL wrapper belong to Cobalt, not Asio.

Find your way through the guide

The guide follows Diataxis: choose a path for what you need now. All paths share the compiled examples and generated API reference on this page.

Tutorial: your first asynchronous program

We will run a program that prints a message, waits for a timer and returns from its event loop. You will see when a scheduled handler actually runs and why the context stays alive while a timer wait is pending.

You need basic C++ knowledge, a webcpp checkout, b2 and a configured native C++20 compiler. For the second run, you also need the Emscripten and Node setup described in Building. Run the commands below from the superproject root. No web server is needed for this first exercise.

1. Open the program

Open libs/asio/example/asio_quick_start.cpp. This is the complete program we will compile, including its headers:

#include <webcpp/asio/io_context.hpp>
#include <webcpp/asio/steady_timer.hpp>

#include <webcpp/test/exit_status.hpp>

#include <webcpp/asio/post.hpp>

#include <chrono>
#include <cstdio>

namespace asio = webcpp::asio;
using namespace std::chrono_literals;

int main() {
    asio::io_context io;
    asio::steady_timer timer(io);

    webcpp::asio::post(io, [&timer] {
        std::puts("posted");
        timer.expires_after(50ms);
        timer.async_wait([](boost::system::error_code ec) {
            if (ec) {
                std::printf("timer error: %d\n", ec.value());
            } else {
                std::puts("timer fired");
            }
        });
    });

    const auto handlers = io.run();  // lint-run: main owns the program's event loop
    std::printf("run returned %zu handlers\n", handlers);
    return webcpp::test::exit_status(0);
}

The context owns the event loop. The timer belongs to that context and stays alive until main ends. post schedules the first handler; it does not call it immediately. That handler prints posted, arms the timer and registers its completion handler. This sequence keeps the output order the same even if the machine pauses before entering run.

2. Run it natively

b2 libs/asio/example//asio_quick_start.output

The build compiles and executes the program, then compares its output with the file beside it, asio_quick_start.expected. On success, b2 saves the captured output in asio_quick_start.output at the build path printed by its run-and-compare action. Open that file; its contents should be:

posted
timer fired
run returned 2 handlers

The last line uses webcpp’s example-test helper to report completion, including after an Asyncify suspension. It leaves page modules without the Node harness unchanged.

Notice that run returns after both handlers have run. The timer’s 50 ms is a requested delay, not a promise about exact wall-clock execution time. The output deliberately shows no measured duration.

3. Run the same source as WebAssembly

b2 toolset=emscripten libs/asio/example//asio_quick_start.output

Node executes the generated WebAssembly using JSPI. Its .output file contains exactly the same three lines. Next, run it with Asyncify:

b2 toolset=emscripten webcpp-suspend=asyncify libs/asio/example//asio_quick_start.output

Again the output is unchanged. These runs exercise the source and its suspension under Node; loading a page in a browser is a separate step in Loading the variant a browser runs. If b2 cannot find a compiler or Node, check Building before changing the program. If the output differs, the example runner prints the difference and fails the build.

4. Follow the next piece of work

You have now run the same event loop natively and with both WebAssembly suspension variants. Follow How to schedule deadlines and cancel a wait to schedule several deadlines and cancel a wait, or How to configure the turn limit to configure a finite chain of posted work. For the reason the browser needs a turn limit, read A turn at a time. Exact contracts are in Guarantees and the generated API reference.

Why asio

Boost.Asio is the ground of asynchronous C++: Boost.Beast, Boost.Cobalt, Boost.MySQL, Boost.Redis and many others are written on it, as templates over its executors, its completion tokens and its stream concepts. WebCPP preserves that programming model while adapting execution and I/O to the deployment target. Native equivalents are Boost.Asio itself. On Wasm, an explicitly shipped implementation provides the backend selected by configuration.

webcpp::cobalt and webcpp::beast share this selected Asio backend. Cobalt supplies coroutine types and a compiled runner. Beast supplies HTTP messages, parsers and serializers, stream-based protocol operations, and explicit browser and WASI host adapters. A browser has no ordinary raw TCP listener: its WebSocket and fetch APIs are separate host facilities with their own security policy. A socket-based server example cannot become a browser listener merely by changing its namespace.

WASI guest sockets instead use the SDK’s pollable or waitable reactor support. They still require runtime network grants. A program using only timers has different prerequisites from one using TCP, TLS, threads or host HTTP. The feature matrix and named application profiles keep those requirements separate.

The browser’s asynchronous model reaches C++. The web’s APIs are asynchronous: promises, events, streams. asio makes a promise and an event source Asio operations: a JavaScript promise is awaitable with any completion token, co_await, a callback or a Cobalt task, and an event source is an operation that completes on the event, so that C++ writes the web’s programs in the web’s own model, and in C++'s.

Emscripten supplies the suspension mechanism through JSPI or Asyncify. WebCPP adds browser configuration, a bounded turn and wakeups from browser events. These are library features, not compiler flags that grant access to facilities absent from the host.

The names

asio’s targets are native, emscripten, wasip2 and wasip3. The table below compares native and browser interfaces; Target and variant capabilities specifies the WASIp2 and WASIp3 subsets. Native equivalents retain Boost type identity. Wasm uses types from the shipped implementation, with browser-specific extensions where required:

Name Native Emscripten

webcpp::asio::io_context

An alias of boost::asio::io_context, with exactly its constructors and members.

A derived context over the shipped scheduler and reactor, the reactor made at construction, and the run family composed with the limit on the handlers one turn runs.

Executors, post, dispatch, bind_executor, completion tokens, co_spawn

Boost.Asio’s.

The shipped Asio backend’s corresponding types and operations.

webcpp::asio::steady_timer, system_timer, basic_waitable_timer

Aliases of Boost’s.

Aliases of the shipped backend’s timers, in the reactor’s timer queue.

Promises and events as operations

None: nothing of the browser exists.

A JavaScript promise and an event source, each an Asio operation.

WebSocket and HTTP clients

Boost.Beast.

webcpp’s beast library: Beast’s interfaces over the browser’s WebSocket and fetch.

ip::tcp, ip::udp: sockets, acceptor, resolver

Aliases of Boost’s.

Class templates of asio’s with Boost’s interfaces: each operation of a socket or an acceptor completes with operation_not_supported unless a transport provides it, and the resolver completes with the entries the browser streams of webcpp’s beast library accept.

ssl: context, stream_base, verify_*, host_name_verification

Aliases of Boost’s, in <webcpp/asio/ssl.hpp>, which brings OpenSSL natively, so that <webcpp/asio.hpp> leaves it out.

A record of the program’s TLS settings, which only the browser streams of webcpp’s beast library read.

A program includes <webcpp/asio.hpp> or the corresponding individual headers and uses webcpp::asio:: for the Asio names, including post, co_spawn, use_awaitable and bind_executor. On native targets these names resolve to Boost, so existing native Boost consumers remain interoperable. Wasm executors and tokens belong to the selected implementation; mixing them with independent Boost.Asio types does not select a compatible backend. See Customize completion tokens and associated traits for custom completion tokens and traits.

The WebAssembly io_context takes its options, io_context_options, as the last argument of each of Boost’s constructors: with none, with an allocator, which it allocates its services and its objects’ state with, and with Boost’s hint of the concurrency it will see, with or without an allocator, so that Boost’s idiom io_context io{1} compiles unchanged. Its one option, max_handlers_per_turn, 100 by default, bounds the handlers one turn of its run family runs on emscripten before it yields to the browser; 0 is taken as 1. WASIp2/P3 currently accept the options without changing their loop. The native Boost type has no browser turn options or max_handlers_per_turn member. Select browser-specific configuration explicitly in portable source.

On emscripten, /webcpp/asio//asio also gives every program the configuration Asio needs to build there, and the link flags of its suspension variant (Building).

Target and variant capabilities

This reference covers the public feature families of webcpp::asio and its Cobalt build target. It does not promise every feature of the complete Boost installation. Supported means the implementation provides the feature; limited requires the qualification below; unverified is not a portability promise. Native behavior also depends on the operating system.

For the explicit feature-by-feature intersection of threads and exception handling, use Feature matrix by library and build profile. It separates Asio from Cobalt and distinguishes public support, isolated probes and unverified combinations.

Build configurations

Target and variant Threads Exceptions Status

Native

OS threads, subject to Boost configuration

On or off

Existing integration; native controls run on macOS arm64.

Emscripten / JSPI

Single or pthread workers

On or off

Wasm exceptions when enabled; M requires isolation and creator-thread affinity.

Emscripten / Asyncify

Single or pthread workers

On or off

JavaScript exceptions when enabled; M has the raw pthread return-value limit below.

WASIp3 / threading=single

Disabled

On or off

Minimal port; both configurations tested with wasi-sdk 34.0 and Wasmtime 50.0.1.

WASIp3 / threading=multi

Experimental cooperative threads

Off

Minimal port; tested with wasi-sdk 34.0’s cooperative sysroot and Wasmtime 50.0.1.

WASIp3 / threading=multi

Experimental cooperative threads

On

Unavailable with the tested SDK: its cooperative sysroot has no C++ exception runtime.

WASIp2 / threading=single

Disabled

On or off

Core, timers, TCP/UDP, forward DNS, CLI streams, Cobalt and TLS; see Build for WASIp2.

WASIp2 / threading=multi

Unavailable

On or off

Rejected: the pinned SDK has no supported P2 pthread runtime/profile.

variant=debug and variant=release select build optimization, not different APIs. The new WASIp3 runtime verification uses Release builds. JSPI and Asyncify are browser suspension variants; they are not WASIp3 variants. The WASIp3 thread setting and exception setting are independent choices, subject to the SDK runtime availability above. Cooperative threads suspend at blocking WASI operations; this does not provide simultaneous CPU execution on multiple cores.

Feature matrix by library and build profile

This is a historical baseline for the WebCPP integration and capability-completion work verified on 2026-11-03, using Boost 1.92.0, Emscripten 6.0.11 and wasi-sdk 34.0. The project now selects Wasmtime 50.0.1 for its regression suites; the original isolated probes used Wasmtime 49.0.3. It is not a list of everything those upstream projects might support in other builds. The 2026-11-06 distribution migration changes type selection and source ownership. The cells below retain their original evidence date; they do not certify the current unsubmitted candidate. Use How-to: consume the shipped implementation for current build rules and Cobalt’s current validation status. The old /webcpp/asio//cobalt target is now a compatibility alias for /webcpp/cobalt//cobalt. Portable consumers use webcpp::cobalt names. Do not infer that an Asio feature has also been tested through a Cobalt wrapper or completion token.

Each cell describes the named feature, not every overload or possible input. Read the profile availability table first: an unavailable profile makes all of its public features unavailable, even if an isolated source file compiles.

Table 1. Status legend
Mark Meaning

T

Tested: the named behavior has local runtime evidence in this profile.

A

Provided by the backend or Boost contract; dedicated runtime validation is pending. Treat this as a validation task, not as a tested support guarantee.

L

Limited: usable only within the restriction explained beside the table.

U

Unverified: there is insufficient evidence to promise this combination.

X

Unavailable through this integration or the tested toolchain.

B

Build integration blocked: WebCPP rejects the library target before compilation. Read the named blocker; this does not establish a platform limit.

P

Probe only: isolated runtime evidence, outside the public library target. This is progress toward a port, not an available application configuration.

C

Compile only: an isolated source compiles; linking and execution are unverified.

N/A

The feature is specific to another environment.

Profile availability

EH on/off means exception-handling=on/off. S/M means threading=single/multi. Every on/off pair below refers to both choices; it does not conceal a requirement for exceptions.

Environment Thread profile EH Asio Cobalt Qualification

Native

S

on

T

T

Existing backend; native evidence is macOS arm64.

Native

S

off

T

L

Cobalt issue 287 applies to pending-task moves.

Native

M

on

T

T

Cobalt runner, IP wrappers and thread completion/join tested.

Native

M

off

T

L

Same tested paths, with Cobalt issue 287.

Native

Asio threads disabled with BOOST_ASIO_DISABLE_THREADS

on/off

U

U

A separate profile with Asio’s thread support disabled has not been validated.

Browser / JSPI

S

on

T

T

Requires a JSPI-capable engine.

Browser / JSPI

S

off

T

L

Cobalt issue 287; use result-based paths.

Browser / JSPI

M

on

T

T

Isolated page and creator-thread affinity.

Browser / JSPI

M

off

T

L

Same profile; Cobalt issue 287 applies.

Browser / Asyncify

S

on

T

T

Uses the configured Asyncify stack.

Browser / Asyncify

S

off

T

L

Cobalt issue 287; use result-based paths.

Browser / Asyncify

M

on

T

T

Isolated page and creator-thread affinity.

Browser / Asyncify

M

off

T

L

Same profile; Cobalt issue 287 applies.

WASIp3

S

on

T

T

Public Cobalt target; Asio threads disabled.

WASIp3

S

off

T

L

Same tested target; pending-task moves retain issue 287.

WASIp3

M, cooperative

on

X

X

SDK 34.0 lacks the cooperative C++ EH runtime.

WASIp3

M, cooperative

off

T

L

Public Cobalt target, including its thread coroutine; SDK cooperative runtime and Cobalt issue 287 apply.

WASIp2

S

on

T

T

Core, DNS, CLI streams, Cobalt and TLS consumers.

WASIp2

S

off

T

L

Same consumers; Cobalt issue 287 applies.

WASIp2

M

on/off

X

X

Pinned SDK has no supported P2 pthread runtime/profile.

Native S is not a promise of no threads. The native build does not set BOOST_ASIO_DISABLE_THREADS. Boost may use internal threads, for example for asynchronous name resolution. Explicitly disabling Asio threads is a different configuration and must be applied consistently to the application and compiled dependencies. It does not disable unrelated libraries’ threads.

Browser S sets BOOST_ASIO_DISABLE_THREADS; explicit M enables pthreads in the application and compiled dependencies. WASIp3 S also disables Asio threads. WASIp3 M uses cooperative threads, not simultaneous CPU execution on multiple cores. The missing cooperative EH runtime is a limitation of the SDK distribution tested here, not proof that threads and exceptions are fundamentally incompatible.

variant=release/debug changes optimization, not these feature declarations. The WASIp3 evidence here uses Release. Native operating-system features remain subject to Boost and the host OS; macOS results are not Windows or Linux tests.

Asio: native

The S/M columns use the build profiles above, not a count of active application threads. The strict thread-disabled profile remains U for all features here.

Feature S / EH on S / EH off M / EH on M / EH off

Context, executors and posting

T

T

T

T

Complete run/poll family

T

T

T

T

Timers, expiry and cancellation

T

T

T

T

Cross-thread post and multiple context runners

A

A

T

T

Strands and thread pools

A

A

A

A

Asio awaitable, co_spawn, result-based timer wait

T

T

T

T

Context and associated-handler allocation routing

T

T

T

T

IPv4 TCP connect/accept, read/write, EOF and cancellation

T

T

T

T

IPv4 UDP single-buffer datagrams

T

T

T

T

UDP multi-buffer send_to / async_send_to

T

T

T

T

UDP multi-buffer receive and connected send

T

T

A

A

Synchronous and asynchronous DNS

A

A

A

A

IPv6 traffic, multicast and socket options

A

A

A

A

TLS through Asio/OpenSSL

T

T

T

T

Process signals, local sockets and serial ports

A

A

A

A

Files, descriptors, pipes and platform-specific Asio backends

A

A

A

A

Browser Promise/DOM bridge and turn limit

N/A

N/A

N/A

N/A

Asio availability follows the native backend, including platform feature macros. A does not mean every operating system supplies every row’s APIs. TLS T refers to the tested Clang/macOS recipe, not an MSVC recipe. Exceptions off retain error-code and callback paths; throwing error paths require the qualification in Exceptions and error handling.

Asio: browser / Emscripten

The first table covers S. The M table below records narrower real-browser worker coverage; S results are not automatically evidence for M. T includes the project’s local Emscripten tests under Node; it does not mean every case was independently exercised in every browser engine. The coroutine timer row also passed in HeadlessChrome 153.0.8010.12 in all four columns, linked for the browser without Node’s raw-filesystem option.

Feature JSPI / EH on JSPI / EH off Asyncify / EH on Asyncify / EH off

Context, run/poll family, posting and timers

T

T

T

T

Bounded turns and explicit browser yield

T

T

T

T

Context and associated-handler allocation routing

T

T

T

T

JavaScript Promise operations and event bridge

T

T

T

T

Promise/event cancellation

T

T

T

T

Socket API with a supplied custom transport

L

L

L

L

Direct native TCP/UDP through the default transport

X

X

X

X

Browser resolver retaining a name for a transport

T

T

T

T

OS DNS lookup through that resolver

X

X

X

X

Asio awaitable, co_spawn, result-based timer wait

T

T

T

T

Strands on the single executor

A

A

A

A

Worker-thread execution

X

X

X

X

TLS settings for a transport

T

T

T

T

Linked OpenSSL through the native/WASI TLS target

X

X

X

X

Supplied WebSocket, HTTP or Fetch stream adapter

X

X

X

X

Host POSIX signals, local sockets and serial ports

X

X

X

X

Native-style files/descriptors through this integration

U

U

U

U

L for sockets means that the default transport reports operation_not_supported; the application supplies a transport with the required semantics. This is not raw browser TCP/UDP access. Browser HTTPS or WSS capabilities do not by themselves supply an Asio/OpenSSL stream adapter. The SSL settings record does not encrypt data. See Sockets and transports.

The run family must execute on a stack configured for suspension. A browser yield gives the host an opportunity to run; it does not guarantee a timer deadline or a rendered frame. EH on uses Wasm exceptions with JSPI and the configured JavaScript exception mechanism with Asyncify.

Browser pthread profiles

These columns use threading=multi and real HeadlessChrome 156.0.8078.4 with isolation headers. Run each context on its constructing thread; post between threads. See Browser workers and main-thread callbacks for lifetime and hosting requirements.

Feature JSPI / EH on JSPI / EH off Asyncify / EH on Asyncify / EH off

Main-context wait woken by a browser event

T

T

T

T

Worker timer, cross-thread wakeup and main DOM handoff

T

T

T

T

Timer cancellation delivered through the main executor

T

T

T

T

Context/handler allocators and queued-handler shutdown

T

T

T

T

Reentrant context destruction with queued work

T

T

T

T

Cleanup when moving a handler throws

T

N/A

T

N/A

Reject running a context from a different thread

T

T

T

T

Multiple simultaneous runners of one browser context

X

X

X

X

Complete S scheduling, transport and Promise suite under M

U

U

U

U

Raw pthread return value after an async suspension

T

T

X

X

The last row is a dependency-only witness. A suspended pthread returning pointer value 42 joins with zero under the pinned Asyncify SDK. The versioned probe fails that assertion; void-return workers with explicit result storage pass in both variants. This runtime path cannot be identified by a target macro. It is not a blanket prohibition of pthreads with Asyncify.

Asio on WASIp2

Both columns use threading=single, SDK 34.0 and Wasmtime 50.0.1. Multiple threads are rejected before compilation. T is limited to the stated consumer contracts, not every Boost.Asio overload.

Feature EH on EH off

Run/poll family, timers and timer cancellation

T

T

TCP connect/accept, partial transfer and shutdown

T

T

UDP scalar, empty datagrams and gathered send_to

T

T

Pending socket cancellation

T

T

Async forward DNS, deferred initiation and associated executor

T

T

Resolver-wide and per-operation cancellation

T

T

Numeric synchronous resolution

T

T

Canonical name, mapped-address policy and async reverse DNS

X

X

Asio timer coroutine

T

T

CLI stream pending read cancellation, allocator and executor

T

T

CLI stream WebSocket client/server, text/binary and close

T

T

UDP multiple-buffer receive and connected multiple-buffer send

T

T

POSIX signals, local sockets and serial ports

X

X

Asio/OpenSSL TLS, roots and peer verification

T

T

Cobalt runner/wrappers and SSL integration

T

L

Parallel threads, thread pools and cross-thread post

X

X

See Resolver contract for resolver flag/allocation limits and Use a supplied CLI byte stream for the host-import blocking boundary. Pollable-based waiting does not make an independently blocking host import preemptible.

Asio: WASIp3

M is the SDK’s cooperative profile. X in its EH-on column reflects the missing runtime, including rows that do not otherwise need exceptions.

Feature S / EH on S / EH off M / EH on M / EH off

Context, run/poll family, posting and timers

T

T

X

T

Cross-thread post and multiple context runners

X

X

X

T

Strands

A

A

X

A

Thread pools

X

X

X

U

Asio awaitable, co_spawn, result-based timer wait

T

T

X

T

Context/timer/post allocators with dedicated allocation counters

T

T

X

T

Allocation routing in UDP gather operations

T

T

X

T

IPv4 TCP connect/accept, read/write, EOF and cancellation

T

T

X

T

TCP composed read/write with multiple buffers

T

T

X

T

IPv4 UDP, including empty datagrams

T

T

X

T

UDP multi-buffer send_to / async_send_to

T

T

X

T

UDP multi-buffer receive or connected send

T

T

X

T

Synchronous resolver: numeric addresses and localhost

T

T

X

T

Asynchronous forward resolver

T

T

X

T

Arbitrary external DNS and network reachability

U

U

X

U

IPv6 numeric scope parsing and formatting

T

T

X

T

IPv6 connections and multicast interoperability

U

U

X

U

Interface-name IPv6 scopes

X

X

X

X

Socket options

L

L

X

L

available / FIONREAD, peek and out-of-band marks

X

X

X

X

TLS through Asio/OpenSSL

T

T

X

T

Process signals, local sockets and serial ports

X

X

X

X

Asio file/pipe/descriptor runtime integration

U

U

X

U

Browser Promise/DOM bridge and browser turn limit

N/A

N/A

X

N/A

Both profiles use native asynchronous forward lookup with a waitable-backed reactor descriptor. Deferred initiation, real localhost lookup, timer progress, cancellation and allocator routing are tested. The cooperative lane also checks two-runner cancellation after the host waitable joins the active wait set. External DNS and network access still depend on host capabilities.

UDP gather/scatter preserves one datagram and uses the caller-associated allocator, including connected sends, truncation, empty buffers and cancellation. The separate context/timer/post counters now cover all three supported WASIp3 profiles; narrowly attributed libc wakeup-pipe allocations remain outside the Asio allocator contract. These scenarios are not a complete audit of every operation. Socket-option limits are in WASIp3 limits and error behavior. TLS support does not automatically validate a Cobalt TLS completion token or boost::cobalt::io::ssl::stream.

Cobalt: native

These cells apply to the existing Cobalt build target. S does not disable boost::cobalt::thread or guarantee that Cobalt cannot create threads.

Feature S / EH on S / EH off M / EH on M / EH off

co_main, posting, timer suspension and exact exit status

T

T

T

T

Await Asio timers with Cobalt’s use_op

T

T

T

T

Cobalt io::steady_timer

T

T

T

T

Await Asio IPv4 TCP/UDP, cancellation and EOF with use_op

T

T

T

T

Cobalt io TCP/UDP wrappers and numeric resolver

T

T

T

T

Tasks, promises, generators and composition algorithms

A

U

A

U

Moving a pending task safely without exception support

N/A

X

N/A

X

Channels and wait groups

A

A

A

A

PMR coroutine allocation

A

A

A

A

Internal coroutine cancellation

A

A

A

A

Automatic SIGINT/SIGTERM cancellation in the runner

A

A

A

A

Cobalt thread coroutine completion and join

U

U

T

T

Cobalt file/pipe/serial/local-socket wrappers

A

A

A

A

Await Asio/OpenSSL TLS through a Cobalt token

T

T

T

T

Cobalt io::ssl::stream via cobalt_ssl

T

T

T

T

The task limitation is Cobalt issue 287; A for other EH-off APIs does not establish universal exception-free safety. The thread coroutine also has internal exception-handling paths that require a dedicated failure-path audit without EH. Native I/O rows are subject to the OS and Boost feature macros. Cobalt’s SSL wrapper is supplied by the optional /webcpp/asio//cobalt_ssl target; plain Cobalt remains independent of OpenSSL.

The M thread test creates a Cobalt thread coroutine and awaits its completion. It does not establish correctness of arbitrary concurrent coroutine composition. The network test uses Asio socket types with Cobalt’s completion token; it does not validate Cobalt’s separate io socket wrappers. The independent cobalt_io test supplies that wrapper evidence, including refused TCP connections, TCP/UDP cancellation and numeric resolution.

Cobalt: browser / Emscripten

The following columns cover S. M has separate evidence below.

Feature JSPI / EH on JSPI / EH off Asyncify / EH on Asyncify / EH off

co_main, posting, timer suspension and exact exit status

T

T

T

T

Runner’s bounded turns

T

T

T

T

Await Asio timers with use_op

T

T

T

T

Cobalt io::steady_timer

T

T

T

T

Await JavaScript Promise operations through Cobalt

T

T

T

T

Await the custom socket transport through Cobalt

U

U

U

U

Direct TCP/UDP using Cobalt’s io socket wrappers

X

X

X

X

Tasks, promises, generators and composition algorithms

U

U

U

U

Moving a pending task safely without exception support

N/A

X

N/A

X

Channels and wait groups

U

U

U

U

PMR allocation and cancellation across all coroutine families

U

U

U

U

Cobalt thread coroutine

X

X

X

X

Host SIGINT/SIGTERM notifications

X

X

X

X

Cobalt file/pipe runtime behavior

U

U

U

U

Native local sockets and serial ports

X

X

X

X

Cobalt io::ssl::stream compiled implementation

X

X

X

X

The runner retains Emscripten’s existing signal registration, but that does not supply POSIX process notifications from a browser host. The successful timer and Promise tests do not establish every Cobalt composition or I/O API. Asyncify tests also measure suspension-stack usage; application call depth still needs an appropriate configured stack, as explained in Use Cobalt with Asio.

M passes the public Cobalt thread posting/completion/join test in all four suspension/EH combinations. Broader composition, cancellation and Promise paths under M remain unverified. The completed-thread join still emits the SDK’s main thread blocking warning; Asyncify also emits its documented successful exit notice. The driver matches only these exact notices. This does not authorize waiting synchronously on a live worker from the browser main thread.

Cobalt: WASIp2

Both columns use threading=single, the public //cobalt or optional //cobalt_ssl target, SDK 34.0 and Wasmtime 50.0.1.

Feature EH on EH off

Runner, bounded posting, timers and exact exit status

T

T

Asio TCP/UDP with use_op and Cobalt IP wrappers

T

T

Pending accept/read/resolver cancellation

T

T

Asio/OpenSSL and Cobalt SSL verified TLS

T

T

Cobalt SSL transfer/shutdown errors and cancellation

T

T

Entropy-backed key generation and failure handling

T

T

Moving a pending task safely without exception support

N/A

X

Thread coroutine, local sockets, serial ports and POSIX signals

X

X

Broader coroutine families and filesystem I/O

U

U

The focused suite has 13 checks per EH profile. Entropy tests observe calls to host getentropy, distinct generated keys and failure handling; they do not measure the host RNG’s entropy strength. TLS uses the shared source-built OpenSSL and embedded/replacement CA provider. Host networking grants and trust policy remain application/runtime requirements.

Cobalt: WASIp3

The public dependency /webcpp/asio//cobalt builds and runs in all three available profiles. M/EH on remains X because SDK 34.0 lacks that runtime. EH-off tests do not remove the pending-task move restriction in issue 287.

Feature S / EH on S / EH off M / EH on M / EH off

Runner without POSIX signal registration

T

T

X

T

Await Asio and Cobalt timers in co_main

T

T

X

T

Return success/failure through the WASI command entry point

T

T

X

T

Await Asio IPv4 TCP/UDP, cancellation and EOF with use_op

T

T

X

T

Cobalt io IPv4 TCP/UDP wrappers, cancellation and EOF

T

T

X

T

Cobalt async resolver: numeric address

T

T

X

T

Task result and eager promise completion

T

T

X

T

Generators, channels and composition

U

U

X

U

Cobalt thread coroutine completion and join

X

X

X

T

Automatic SIGINT/SIGTERM cancellation

X

X

X

X

Cobalt file/pipe/descriptor runtime integration

U

U

X

U

Cobalt local sockets and serial ports

X

X

X

X

Await Asio/OpenSSL TLS with a Cobalt token

T

T

X

T

Cobalt io::ssl::stream via cobalt_ssl

T

T

X

T

Numeric asynchronous resolution is tested through Cobalt’s compiled resolver in the supported profiles above. WASIp3’s single-thread and cooperative profiles use the native asynchronous forward resolver; the Asio consumers test localhost lookup, deferred initiation, progress and cancellation. Arbitrary external DNS access depends on host policy and is not established by localhost or numeric consumers.

Historical Cobalt source integration

At the baseline revision, the target built the normal compiled archive, replacing its endpoint and acceptor source files with checked private copies. The private header overlay uses Asio capability macros to omit unsupported local-socket, signal and serial APIs. Seqpacket declarations are omitted when that socket type is unavailable. Single-thread builds omit the thread source and declaration; cooperative builds include it. Native and browser builds retain their original sources and headers.

The application, archive and replacement runner used the same patched Asio headers, thread profile and exception setting. No system Cobalt archive is linked, and installed Boost files are never modified. Input/output hashes pin the compatibility patch to Boost 1.92. A changed upstream input was rejected. This consumer-time overlay was superseded by the explicit source distribution described in How to link the integration. The native core no longer acquires the Wasm corrections; the corrected native SSL wrapper is the approved exception.

The public-target tests cover both Cobalt completion tokens applied to Asio sockets and Cobalt’s own compiled TCP/UDP wrappers, with IPv4 loopback traffic, refused TCP connections, TCP EOF and TCP/UDP cancellation. TLS tests add the ordinary Asio/OpenSSL stream and Cobalt token, with custom or embedded CAs and peer identity verification.

SDK 34.0 maps nonzero command returns to failure: the host statuses are 0 for co_return 0 and 1 for co_return 7. The status driver checks both output and status, so a trap cannot satisfy the failure case. No host shutdown protocol has been added. See Why the Wasm runner changes and Completion and limitations.

Exceptions and error handling

Behavior EH on EH off

Error-code overloads and callback error parameters

Available where the underlying operation is available

Same error channels; no exception is needed to report an ordinary I/O error

Result/tuple adapters around an asynchronous wait

Available

Available for the tested paths; underlying operation support still applies

Throwing overload invoked on an error

Can report an exception according to the API contract

May be excluded by the wrapper or reach the fatal Boost exception handler; do not treat it as an error-code overload

Exceptions escaping a coroutine

Follows the coroutine’s documented propagation policy

No guarantee of recoverable propagation; use supported result-based paths

Cobalt pending-task move with libc++

No exception-disabled limitation claimed here

Known abort risk linked to Cobalt issue 287

WASIp3 cooperative profile in SDK 34.0

Missing runtime in this distribution

Available for the tested Asio feature set

Result adapters do not repair a library operation that constructs an exception object internally. The Cobalt EH-off build warning is a configuration warning, so the compiler’s warnings-as-errors setting does not turn that warning into a build failure. It remains a restriction the application must account for.

Restrictions, causes and application consequences

Restriction Cause Consequence or required work

WASIp3 cooperative threads with EH

SDK 34.0’s cooperative sysroot is built without the C++ exception runtime

Use S/EH on or M/EH off. Supporting M/EH on needs a matching runtime build and runtime validation, not just adding -fexceptions to an application.

Native S versus disabled thread support

threading=single does not define BOOST_ASIO_DISABLE_THREADS natively

Native S can still use internal threads. Explicit thread disabling needs consistent library/application settings and its own validation.

Browser M hosting and affinity

Pthreads need isolated shared memory; JavaScript values have thread affinity

Use the creator thread to run each context and the main executor for DOM work. Configure COOP/COEP when hosting; compiler macros cannot verify deployment.

Browser sockets and TLS

The default transport returns operation_not_supported; only a transport interface and TLS settings are supplied

Supply and validate an adapter. These APIs do not expose raw browser TCP/UDP or provide an OpenSSL stream. See Sockets and transports.

WASI reverse DNS and canonical/mapped-name policies

The host lookup interface supplies forward address results

Unsupported async policies report operation_not_supported. Host DNS permission remains a runtime fact; numeric and forward lookup paths are available.

WASIp3 UDP buffer sequences

The tested wasi-libc lacks the vectored socket calls used by stock Asio

The port supplies gather sends and scatter receives, including connected sends, with temporary allocator-aware storage. See WASIp3 limits and error behavior.

WASIp3 socket options and IPv6 scopes

The port exposes only the tested libc interfaces

Missing options return operation_not_supported; interface-name scopes are rejected. Numeric IPv6 scope parsing is tested, IPv6 traffic is not.

WASIp3 process signals and OS-specific devices

This port has no POSIX signal service, local-socket family or serial backend

There is no automatic SIGINT/SIGTERM cancellation. Explicit operation cancellation works; a host shutdown protocol would be separate integration work.

Cobalt pending-task move without EH

Boost 1.92’s move path can construct an exception with std::make_exception_ptr; the reported libc++ no-EH configuration aborts

See issue 287. This concerns the pending task’s move implementation, not every std::move or every coroutine. Result adapters do not repair this internal path. Other coroutine families still need their own success, error and cancellation tests.

Cobalt io::ssl::stream

Available through an optional target with a checked Boost 1.92 patch

/webcpp/asio//cobalt_ssl adds the wrapper, state/callback corrections and native_ssl_handle() extension. Native, P2 S and supported P3 profiles are available; browser TLS remains host-owned. See Use the corrected SSL stream for trust configuration and the STARTTLS contract.

Validation still required

A and U are open validation work, not reasons to skip testing. C needs linking and runtime checks. P needs the same behavior tested through the public target. This inventory groups the remaining gaps; each test must record its target, thread/EH profile, tool versions and observed success or supported failure.

Pending area Required evidence before claiming tested support

Native profile coverage

Test a consistently Asio-thread-disabled build separately. macOS results do not validate Windows or Linux platform-specific APIs.

Strands, pools and concurrent Cobalt

Check strand serialization and pool shutdown/cancellation in each supplied profile. The Cobalt thread completion/join test does not cover cancellation, exception propagation or concurrent coroutine composition.

Network coverage beyond current loopback cases

Extend resolver variants, IPv6 traffic, multicast and supported socket options. Native scatter/connected UDP now has focused S controls. For WASIp3, record host network/DNS grants and test both permitted and denied operations.

Cobalt coroutine families

Add lifecycle, result/error, cancellation and cleanup cases for tasks, promises, generators, channels, wait groups and composition; measure PMR allocation/release. Retain issue 287’s negative/control evidence separately.

Cobalt network wrappers and TLS

Extend IP wrappers to broader resolver/IPv6 cases. Cobalt SSL handshake and terminal transfer cancellation, buffered ClientHello, STARTTLS, peer verification, clean/truncated/cancelled shutdown and partial composed transfers are covered. Connection recovery after terminal cancellation is not established.

Browser custom transport and I/O

Await the custom transport through Cobalt with success/error/cancellation; establish what filesystem/pipe APIs are exposed before testing their runtime behavior. Node filesystem access is not browser filesystem evidence.

OS-specific I/O and signals

Validate each native file/descriptor/pipe/serial/local-socket backend where available, and runner cancellation on an actual process signal. WASIp3 file/pipe probes need linking, granted host resources and runtime checks.

Browser engines and unavailable profiles

Record real-browser runs for each supported engine; Node evidence alone does not cover them. Browser M has the focused Chrome coverage above, not the complete S suite. WASIp3 M/EH on needs a matching SDK runtime before validation.

Evidence and maintenance

The matrix records existing local results; updating this page does not run CI or establish new feature coverage. T is limited to the behavior exercised by these tests, not a blanket certification of an upstream library.

Feature family Evidence to maintain

Native/WASIp3 context, TCP/UDP, timers and threads

wasi_core, explicit wasi_core_threads, wasi_contract, wasi_coroutine, run_family_native/wasip3, timers_native/wasip3

UDP multi-buffer sends and their allocators

wasi_udp_gather; keep receive and connected-send limits distinct

Native M run/poll and allocation coverage

run_family_native, allocation_native and wasi_udp_gather, Release with threading=multi and both EH settings

WASI datagram sequences and DNS

capability_wasi plus wasi-dns-threads: retries, canonical cleanup, timer progress, cancellation and two-runner ownership

Browser M contexts and main-thread handoff

test/browser//browser-workers, both suspensions and EH settings; test/browser/probes/pthread_return.cpp is the separate SDK counterexample

P2 Cobalt/TLS

test/wasip2_tls_cobalt and its wasip2-tls lane in both EH profiles

Browser scheduling, timers, Promise/event bridge and transports

reactor, run_family, turn_limit, timers, allocation, promise, event, sockets, transport, resolver, and their declared suspension/EH variants

Asio coroutine timer in browser configurations

asio_coroutine_exceptions_on/off and Asyncify counterparts under Node; the same coroutine timer also passed in HeadlessChrome 153.0.8010.12 for all four variants. The browser links replace -sNODERAWFS=1 with -sENVIRONMENT=web. The test uses awaitable, co_spawn and result-based timer completion.

Cobalt native/browser runner and timers

cobalt_exceptions_on/off_native, Emscripten counterparts and Asyncify counterparts; the cobalt and cobalt_asyncify exact-exit driver lanes

Cobalt token with native Asio sockets

cobalt_network_exceptions_on/off, in S and M: IPv4 TCP/UDP data, pending-receive cancellation and TCP EOF

Browser Promise/Cobalt interoperability

promise_cobalt_exceptions_on/off and Asyncify counterparts

WASIp3 runner compile regression

cobalt_main_wasip3, with S EH on/off and M EH off

WASIp3 Cobalt runtime tests

cobalt_wasi, cobalt_network_wasi, cobalt_io, explicit cobalt_thread and the cobalt_wasip3 status lane, all through the public target

Cobalt TLS over Asio/OpenSSL

tools/openssl/test//cobalt_tls_client and tools/openssl/test/tls.py --embedded

Cobalt SSL wrapper

tools/openssl/test//cobalt_ssl_client with tls.py --embedded --require-sni, including --client-arg=buffered; cobalt_ssl_state and cobalt_ssl_cancel with --state-test, for TLS 1.2/1.3 in the recorded native/WASIp3 profiles. WASIp2 has separate peer, state and cancellation evidence from test/wasip2_tls_cobalt//wasip2-tls in S with EH on/off

Native/WASIp3 TLS

Superproject tools/openssl/test/run.py: verified TLS 1.2/1.3 handshakes, application data, shutdown and rejected peer identities in the recorded profiles

The commands in Build and test a WASIp3 program and Checks and historical suspension storage reproduce the registered lanes. To promote U, C or P to T, record a successful runtime test through the intended public target, including the relevant thread and EH profile. Keep unsupported-operation tests as evidence of a limit, not evidence that the rejected operation is supported. Update this matrix when a backend, toolchain, capability guard or test result changes.

Require a capability at compile time

<webcpp/asio/config.hpp> defines the following read-only macros as 0 or 1. Use #if, not #ifdef, to inspect them. Do not define these capabilities on the command line: the header rejects attempts to override them.

Macro suffix after WEBCPP_ASIO_ Meaning of 1

HAS_SOCKET_BACKEND

Native/WASI TCP and UDP backend, subject to runtime grants and options.

HAS_OPENSSL_BACKEND

This target supports the optional source-built OpenSSL provider.

HAS_HOST_DNS

Forward lookup through the native/WASI host, subject to host DNS policy.

HAS_REVERSE_DNS

Native reverse lookup; the WASI interface is forward-only.

HAS_THREADS

Boost.Asio thread support is enabled in this build, including cooperative threads.

HAS_BROWSER_BRIDGE

Emscripten JavaScript events and Promises can reach the executor.

HAS_BROWSER_WORKERS

Emscripten pthread build with Asio thread support.

HAS_WASI_STDIO

The WASIp2 pollable CLI stream adapter is available.

HAS_LOCAL_SOCKETS, HAS_SIGNALS, HAS_SERIAL_PORT

Native target with the corresponding Boost.Asio facility enabled.

WEBCPP_ASIO_HAS_OPENSSL=1 is different: it declares that the optional compiled dependency was selected. /webcpp/asio//openssl and //tls supply it together with the matching provider. Outside B2, the application must also supply the matching OpenSSL headers and libraries. Merely defining it cannot satisfy the linker. ssl.hpp rejects native/WASI use without that dependency; Emscripten keeps its portable TLS settings record.

Define a WEBCPP_ASIO_REQUIRE_* switch to a nonzero integer before the first WebCPP include, or on the compiler command line, to require SOCKET_BACKEND, OPENSSL, THREADS, LOCAL_SOCKETS, SIGNALS, SERIAL_PORT or REVERSE_DNS. An absent switch or a value of zero imposes no requirement. The default permits portable applications to select runtime alternatives, including browser transports. Apply configuration consistently to every translation unit.

This compiled example requires a real socket backend and still handles a runtime refusal from the host:

// State requirements before the first WebCPP include, or use a compiler define.
#define WEBCPP_ASIO_REQUIRE_SOCKET_BACKEND 1
#include <cstdio>
#include <webcpp/asio/io_context.hpp>
#include <webcpp/asio/ip/tcp.hpp>
#include <webcpp/test/exit_status.hpp>

int main() {
    webcpp::asio::io_context context;
    webcpp::asio::ip::tcp::socket socket(context);
    boost::system::error_code error;
    if (socket.open(webcpp::asio::ip::tcp::v4(), error)) {
        // A compiled backend does not imply that the host granted socket access.
        const auto message = error.message();
        (void)std::fprintf(stderr, "socket open: %s\n", message.c_str());
        return webcpp::test::exit_status(1);
    }
    std::puts("TCP socket opened");
    return webcpp::test::exit_status(0);
}
TCP socket opened

The browser-specific headers diagnose a non-Emscripten target before including Emscripten headers. wasi/stdio_stream.hpp diagnoses targets without the P2 CLI adapter. B2 rejects unsupported SDK/thread/EH combinations and checks the private WASI descriptor ABI. A compiler cannot determine network grants, available peers, trust roots, a page’s isolation headers or whether a host import will block. Those conditions retain runtime errors or the documented host behavior.

Execution and integration features

In the following tables, browser covers both JSPI and Asyncify. Their API capabilities are the same; their suspension and exception implementations differ. The separate Asio on WASIp2 table records the P2 profile.

Feature Native Browser WASIp3 single WASIp3 cooperative

io_context, executors, post, dispatch, run/poll family

Supported

Supported

Supported

Supported

Steady/system timers, expiry changes and cancellation

Supported

Supported

Supported

Supported

Context and associated-handler allocators

Boost contract

Supported

Context/timer/post counters tested

Context/timer/post counters tested; named libc pipe allocations separate

Multiple threads posting or running a context

Boost contract

Cross-thread post in M; one creator-thread runner per context

Unavailable

Tested: wakeup and two runners

C++20 Boost.Asio awaitable / co_spawn

Timer coroutine tested

Timer coroutine tested under Node and Chrome

Timer coroutine tested

Timer coroutine tested

Boost.Cobalt and the co_main runner

Supported with qualifications in Use Cobalt with Asio

Supported with the same qualifications

Supported with qualifications in Use Cobalt with Asio

Supported without exceptions; cooperative thread coroutine tested

Promise operations and DOM/event bridge

Not applicable

Supported

Not applicable

Not applicable

Browser turn limit, explicit browser yield

Not applied

Supported; default limit 100

Not applied

Not applied

Browser loader and suspension-variant manifest

Not applicable

Supported

Not applicable

Not applicable

WASIp3 keeps Boost.Asio’s scheduler and select reactor. It does not use the JavaScript event bridge or the browser’s handler-count limit. Its syscalls suspend through wasi-libc and the host’s Component Model implementation.

The public Cobalt target builds its static archive with checked compatibility headers and sources on WASIp3. Timers, TCP/UDP and cancellation are exercised through both Asio completion tokens and Cobalt’s own wrappers. The optional /webcpp/asio//cobalt_ssl target adds Cobalt’s SSL wrapper with verified TLS and handshake/transfer cancellation, including partial composed operations. Truncated and cancelled shutdown are also tested; see Use the corrected SSL stream. See Historical Cobalt source integration for integration details and Validation still required for the historical gap inventory. The current Cobalt guide records the subsequent coroutine and application tests. It has no automatic SIGINT/SIGTERM shutdown bridge on WASIp3; internal coroutine cancellation is a separate mechanism. See Why the Wasm runner changes.

Networking features

Feature Native Browser WASIp3 single WASIp3 cooperative

TCP connect, accept, read/write, endpoint queries

Supported

Requires custom transport

Supported

Supported

TCP composed read/write with buffer sequences

Supported

Requires custom transport

Supported; partial transfers

Supported; partial transfers

UDP send/receive, including empty datagrams

Supported

Requires custom transport

Supported

Supported

UDP send_to / async_send_to with multiple nonempty buffers

Boost contract

Transport dependent

Supported; concatenated copy

Supported; concatenated copy

UDP receive or connected send / async_send with multiple nonempty buffers

Boost contract

Transport dependent

Supported; gather/scatter copy

Supported; gather/scatter copy

Asynchronous cancellation and TCP EOF

Supported

Transport dependent

Tested

Tested

IPv4 loopback TCP/UDP

Tested

Requires custom transport

Tested

Tested

IPv6 socket connections

OS dependent

Requires custom transport

Unverified

Unverified

IPv6 numeric scope parsing/formatting

Supported

Browser endpoint representation

Tested

Tested

IPv6 interface-name scopes

OS dependent

Not a host interface lookup

Unavailable

Unavailable

Synchronous resolver

Supported

Retains names; no DNS lookup

wasi-libc resolver

wasi-libc resolver

Asynchronous resolver

Boost thread pool

Retains names; no DNS lookup

Native async host lookup

Native async host lookup

available() / FIONREAD, peek, out-of-band marks

OS dependent

Transport dependent

Unavailable in tested libc

Unavailable in tested libc

Socket options

OS dependent

Transport dependent

Limited to libc’s options

Limited to libc’s options

TLS through /webcpp/asio//openssl

Source-built OpenSSL; native Clang/GCC recipe

Settings record only

Source-built OpenSSL; TLS 1.2/1.3

Source-built OpenSSL; TLS 1.2/1.3, exceptions off with SDK 34

Embedded CA defaults and complete replacement through /webcpp/asio//tls

Supported; no certificate files required

Helper returns unsupported_target; browser owns trust

Supported; no certificate directory preopen

Supported; no certificate directory preopen, exceptions off with SDK 34

WebSocket/HTTP browser streams

Separate Beast library

Separate adapter, not supplied here

Not supplied here

Not supplied here

Process signals, local sockets, serial ports from Boost

OS dependent

Not supplied here

Disabled

Disabled

OpenSSL local coverage includes native macOS arm64 single/multi with exceptions on/off using Clang, WASIp2 and WASIp3 single with exceptions on/off, and WASIp3 cooperative with exceptions off. A GCC 15 native multi-threaded build with exceptions also passed the TLS tests. Linux Clang/GCC mappings are implemented but not runtime-tested on this macOS host. The native MSVC recipe is implemented; this local macOS matrix does not establish Windows runtime coverage. The source library uses OS threads natively and cooperative threads on WASIp3; it does not make cooperative execution CPU-parallel. TLS tests cover verified handshakes, asynchronous application data, clean shutdown and rejected peer identities. The embedded CA factory’s trust policy, update procedure and local checks are documented in How-to: configure trusted certificate authorities.

The browser’s default socket transport reports operation_not_supported for network operations. The browser resolver does not perform DNS; see Sockets and transports. A TLS settings record is not a TLS implementation.

WASIp3 limits and error behavior

  • TCP buffer sequences advance one nonempty buffer per syscall when necessary. Partial reads and writes are valid Asio behavior; composed async_read and async_write continue until their completion condition is met. No temporary heap buffer is introduced to concatenate a sequence.

  • UDP send_to and async_send_to concatenate multiple nonempty buffers into one datagram because the tested wasi-libc does not provide sendmsg. Concatenation visits the entire sequence before Asio’s native iovec limit. It copies the payload once into temporary storage: the context allocator supplies synchronous storage, and the handler’s associated allocator supplies asynchronous storage. The operation owns asynchronous storage until completion or destruction and releases it before invoking the handler. Scalar, empty and single-nonempty-buffer sends need no temporary allocation or payload copy. The gather path rejects payloads above 65,535 bytes with message_size before allocating or reading their data; the host may enforce a smaller IP limit. Allocation failure follows the supplied allocator’s failure behavior.

  • Connected send / async_send use the same single-datagram gather path. Multi-buffer receives read one datagram into temporary storage and scatter the received bytes across the destination sequence. A short destination truncates the datagram; its remainder is not delivered as another packet. Empty buffers do not split a datagram. Empty datagrams are delivered. Scratch allocation follows the synchronous context or asynchronous handler allocator, as for sends.

  • Synchronous resolution uses wasi-libc. Actual hostname lookup requires host permission; numeric resolution does not need DNS. Both thread profiles use the native asynchronous forward-lookup import and a waitable-backed descriptor for async_resolve. Initiation is deferred through the executor and other timers progress while the lookup is pending. Resolver-wide and per-operation cancellation preserve the normal completion channel. No hidden thread or periodic DNS polling is introduced. Canonical names, mapped-address policies and asynchronous reverse lookup are explicitly unsupported.

  • Interface-name scopes such as %eth0 are rejected. Decimal IPv6 scopes in the range 0 through 4294967295 are accepted.

  • Missing socket options, including linger, broadcast, debug, don’t-route, out-of-band-inline and low-water marks, report operation_not_supported. Other options remain subject to wasi-libc and host support. Multicast and detailed socket-option interoperability have not been validated.

  • WASI has no ESHUTDOWN. The port maps Asio’s shut_down to EPIPE, which wasi-libc uses; it therefore shares the numeric value of broken_pipe.

  • Error-code overloads and asynchronous completion retain their error channels. With exceptions disabled, invoking a throwing overload on an error can still reach Boost’s fatal exception handler. Prefer explicit error-code/result paths.

  • Cobalt uses the same platform restrictions through its public B2 target. Its async resolver uses the same native lookup in both thread profiles. TLS through Asio/OpenSSL with Cobalt tokens uses application-selected trust roots and host network capabilities; embedded roots require no certificate filesystem preopen. See TLS: build OpenSSL from source on native and WASI and How-to: configure trusted certificate authorities.

These are current port boundaries, not claims that WASIp3 itself can never support the missing operations. The compatibility patch belongs to Boost.Asio’s platform layer; implementing the missing POSIX entry points such as sendmsg/recvmsg belongs in wasi-libc. The current port avoids pretending those entry points or process signals exist.

Building

asio is developed inside the webcpp superproject, as a Boost library is developed inside Boost. Its headers share Boost’s executor model; the browser bridge and optional Cobalt entry point have compiled support units. A b2 program uses /webcpp/asio//asio on native, Emscripten and WASIp2/P3:

exe app : app.cpp /webcpp/asio//asio ;

The target adds asio’s headers, Boost’s and the webcpp configuration dependency. <webcpp/asio/config.hpp> includes <webcpp/config.hpp> first; WEBCPP_NO_EXCEPTIONS selects the exception-free policy of WebCPP-owned adapters. An explicit WEBCPP_ASIO_NO_EXCEPTIONS remains supported. Neither macro removes the overloads inherited from native Boost or the shipped WASI backend, nor changes the compiler’s exception mode. Use matching compiler flags across the application and its sources; with exceptions disabled, prefer error_code overloads and asynchronous error/result channels to avoid fatal error paths. On emscripten the target also supplies everything else a program needs there: the define Asio needs to build, embind, the JavaScript functions asio calls, compiled once in src/browser_src.cpp, the link flags of the program’s suspension variant, and the variant in the program’s name:

alias headers : : : : <include>include <library>/boost//headers
  <library>/webcpp/config//config ;

alias asio : : : : <include>include <library>/boost//headers
  <library>/webcpp/config//config
  <toolset>clang-wasip2:<library>/webcpp/asio-runtime//runtime
  <toolset>clang-wasip3:<library>/webcpp/asio-runtime//runtime
  <toolset>emscripten:<linkflags>-lembind
  <toolset>emscripten:<linkflags>-Wl,--export=emscripten_stack_get_current
  <toolset>emscripten:<linkflags>-Wl,--export=_emscripten_stack_restore
  <toolset>emscripten,<threading>multi:<linkflags>-Wl,--wrap=__syscall_poll
  <toolset>emscripten:<source>browser-src
  <toolset>emscripten,<webcpp-suspend>jspi:<linkflags>-sJSPI
  <toolset>emscripten,<webcpp-suspend>asyncify:<linkflags>-sASYNCIFY
  <conditional>@asyncify-stack
  <toolset>emscripten:<tag>@webcpp%suspend-tag ;

The Emscripten S profile sets BOOST_ASIO_DISABLE_THREADS. Explicit threading=multi enables pthreads consistently in the application, browser support unit and optional Cobalt archive. Asio’s inline namespace differs with and without threads, so all translation units and compiled dependencies must use matching settings.

The bridge’s JavaScript uses stackSave and stackRestore. On Emscripten 6.0.11, their native dependencies must survive the native link before EM_JS_DEPS is processed. The target therefore exports emscripten_stack_get_current and _emscripten_stack_restore explicitly, including in optimized JSPI builds. A build outside b2 must keep the same link flags shown above.

For direct compilation or another build system, see How-to: consume the shipped implementation for the source inventory, SDK verification and external consumer recipe.

Browser workers and main-thread callbacks

Select threading=multi together with either suspension variant and exception setting. The public target supplies -pthread through the toolset and the threaded main-poll adapter. It does not move main to a worker automatically. The M-only -Wl,--wrap=__syscall_poll adapter uses the pinned SDK’s async poll on the actual browser main thread; worker waits retain the SDK proxy route. This private SDK boundary must be rechecked when Emscripten is upgraded.

A browser io_context must run on the thread that constructed it. Other threads may post ordinary C++ work to its executor. One context does not support simultaneous runners; keep separate contexts per worker. Running it from a different thread triggers a checked-build assertion and returns zero when assertions are disabled, before accessing thread-local JavaScript values.

browser::main_thread_context supplies an Asio executor for DOM callbacks. Construct and destroy that context on the actual browser main thread; copy its executor to workers and use webcpp::asio::post or bind_executor. Obtain JavaScript objects inside the main callback and send ordinary C++ data back to the worker. Do not move emscripten::val handles between threads. The context must outlive calls using its executors, and destruction must not overlap such calls. If a callback destroys its context, an external allocator resource must outlive the callback because queue control survives until it returns. Queued handlers are discarded during shutdown. Handler storage follows its associated allocator; the SDK owns its separate queue/notification storage.

A main-executor callback runs on an ordinary browser callback stack. It must not call a JSPI/Asyncify suspending import or drive the context’s run family. Normal C++ coroutine suspension that returns to its caller is a different mechanism. If moving or invoking a handler throws, queued handlers are discarded and further queued submissions are discarded. Inline main-thread dispatch retains its ordinary direct-call behavior. The exception propagates to the browser callback boundary; recovery after that failure is not promised. Cancellation still belongs to the originating operation; posting a callable does not add a new cancellation protocol.

The host needs a secure context, workers and shared memory. Serve the page with Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp, and check crossOriginIsolated. These deployment requirements cannot be diagnosed in config.hpp. Applications choose their worker-pool size and must retain the runtime while work is pending. Never block the browser main thread waiting for a live worker.

The local lane covers JSPI/Asyncify with EH on/off in an isolated Chrome page:

b2 libs/asio/test/browser//browser-workers toolset=emscripten \
  threading=multi webcpp-suspend=jspi exception-handling=on

Repeat with webcpp-suspend=asyncify and exception-handling=off for the other profiles. The driver tests actual main/worker wakeup, DOM handoff, cancellation, allocator routing, queued shutdown and Cobalt thread completion. The exact coverage appears in Browser pthread profiles.

Pinned Asyncify pthread return-value limit

A dependency-only witness is versioned in test/browser/probes/pthread_return.cpp. It suspends a pthread entry, returns pointer value 42, and joins without blocking the browser main thread. With Emscripten 6.0.11, JSPI preserves 42; Asyncify returns zero and the witness fails. This does not involve Asio. Void-return worker paths with explicit C++ result storage are tested successfully in both variants. This runtime path is not identifiable from a target define, so no broad compile-time ban is imposed.

To reproduce from the superproject root using the configured SDK:

em++ libs/asio/test/browser/probes/pthread_return.cpp \
  -pthread -sPTHREAD_POOL_SIZE=1 -sJSPI -o worker_return-jspi.js
node libs/asio/test/browser/run.mjs --mode workers worker_return-jspi.js

Replace -sJSPI with -sASYNCIFY -sASYNCIFY_STACK_SIZE=8192 and change the output name for the failing control. The failure is retained as evidence of an SDK limitation, not counted as a passing application test.

The two suspension variants

On emscripten, run suspends main into the browser’s event loop in one of two ways, each a variant of the program built from the same sources:

Variant What suspends Link flags Exceptions Browsers

jspi, the default

JavaScript Promise Integration: the suspending imports, Emscripten’s __syscall_poll and asio’s yield, are wrapped in WebAssembly.Suspending, and main, on whose stack run executes, in WebAssembly.promising.

-sJSPI

WebAssembly exceptions, -fwasm-exceptions

those with JSPI

asyncify

Emscripten’s Asyncify: the compiler instruments every function that may reach a suspending import, so that the stack unwinds into the browser and is rewound when the program resumes.

-sASYNCIFY, -sASYNCIFY_STACK_SIZE, measured

JavaScript-based exceptions, -fexceptions

every browser

A build asks for a variant with the feature webcpp-suspend, on b2’s command line, b2 toolset=emscripten webcpp-suspend=asyncify, or in a program’s requirements, <webcpp-suspend>asyncify. The feature is propagated, so that every library a program uses is built for its variant, and composite, since Asyncify does not work with WebAssembly exceptions: emcc only warns, and the program traps at run time with RuntimeError: unreachable when it suspends inside a catch block. So asyncify asks for JavaScript-based exceptions itself, and jspi keeps b2’s WebAssembly ones; a build with exception-handling=off compiles with -fno-exceptions in either:

feature.feature webcpp-suspend : jspi asyncify : propagated composite ;
feature.compose <webcpp-suspend>asyncify : <exception-handling-method>js ;

Emscripten finds the suspending imports itself, so no list of them is given. ASYNCIFY_IGNORE_INDIRECT is not set, since the path from main to the reactor’s select passes a virtual call, Asio’s scheduler_task::run. Asyncify adds instrumentation and increases the program size. With -O3 and exceptions enabled, the release examples measured 1.88 to 1.91 times the JSPI WebAssembly size. The ratio depends on the optimization profile and exception setting; see How to compare release sizes and timings for the six-profile matrix with exceptions on and off, separate JavaScript byte counts, build and execution timings, and reproduction commands.

Asyncify’s stack

Asyncify saves a suspension in a stack of its own, of a fixed size, which ASYNCIFY_STACK_SIZE sets and Emscripten allocates at every suspension: each frame from main down to the suspending import writes its locals there as it unwinds, and a suspension that does not fit traps with RuntimeError: unreachable, which Emscripten follows, in a build with assertions, with "may be due to ASYNCIFY_STACK_SIZE not being large enough". The trap is certain, at every suspension that deep, but only there. So asio does not keep Emscripten’s default: it sets the size to at least twice the deepest suspension its tests reach, measured exactly, as the bytes each unwind wrote, read from Asyncify’s own data when the unwind stops. In the measurements of 2026-10-11, the deepest build was one compiled with optimization and linked without it, as b2’s release variant links on emscripten: its deepest suspension in the tests wrote 3,540 bytes, against 1,272 in a debug build. Linked with optimization, a suspension writes a sixth or less of what it writes linked without: 416 bytes at most in the tests, and 384 for the run family’s deepest path, against 2,404. Half of the stack is so left to the program’s own frames, whose depth asio cannot know.

A program that calls run deep in its code, or whose frames above run are large, measures its own suspensions the same way and asks for more with the feature asyncify-stack-size, which asio declares: in its requirements, <asyncify-stack-size>16384, or on b2’s command line, asyncify-stack-size=16384. Its values are powers of two from 8192, asio’s size and the default, to 1048576; a smaller one stops the program’s compilation at an #error of <webcpp/asio/config.hpp>, which says why. asio’s usage requirements read the feature, so that its flag ends last on emcc’s command line, where emcc keeps the last: a <linkflags> of the program’s own would come before asio’s and be ignored.

A suspension that does not fit is found when the unwind stops, after its frames wrote past Asyncify’s stack into the heap; the program aborts there. Nothing of the program runs afterwards: no destructor or atexit handler, no timer or event of asio’s; only JavaScript of the page’s own that calls an export could still enter it.

Held by asyncify_stack, with exceptions and without them, in debug, in release and in release linked with -O3, which measures every suspension of the run family, the reactor’s wait and the yield under each member that makes one, inside a try and a catch block too, and fails when one of them leaves less than half of the stack, or when the reading finds no unwind, no byte written, or no blocking poll in a reactor-wait case; by every test of the asyncify lane, which links the same size and traps if a suspension of its own does not fit; by asyncify_stack_size_default and asyncify_stack_size_raised, which read the size the program was linked with, and asyncify_stack_size_refused, which does not compile, beside asyncify_stack_size_control, which does; and by bridge_abort, in each variant, where an event called from JavaScript after the runtime aborted reaches no registration.

The reactor-wait cases keep outstanding work until a JavaScript macrotask posts the handler that releases it. Each delays entry by 25 ms, past the expiry of the former 1 ms C++ timer, and requires a poll with a nonzero timeout. A timer that already expired can finish in the initial nonblocking poll: that poll suspends too, but its shorter stack is not evidence for the waiting path. The yield cases cover run, run_for and run_until separately.

On 2026-10-14, with Emscripten 6.0.11 and Node 26.7.0, the corrected asyncify_stack test measured these maxima from scratch, in bytes:

Build Exceptions on Exceptions off

Debug

1164

844

Release, unoptimized link

2896

1940

Release, link with -O3

384

288

Each of the eleven paths with exceptions and nine without stayed below 4096 bytes, half of the configured 8192. These are measurements of the run-family test, not a bound on a user’s own call frames.

The artifacts are named and placed as Boost’s own build names and places them: one directory level per toolset, variant and property that is not the default, and a file name that carries the program’s tags joined by -, the toolset’s version, 60 for Emscripten 6.0.11, d for a debug build, and the suspension variant. The default variant adds no directory level:

Build The program app

debug, jspi

bin/emscripten-6.0.11/debug/.../app-60-d-jspi.js

debug, asyncify

bin/emscripten-6.0.11/debug/.../webcpp-suspend-asyncify/app-60-d-asyncify.js

release, jspi

bin/emscripten-6.0.11/release/.../app-60-jspi.js

each beside its .wasm.

Loading the variant a browser runs

Build a page program and its two variants with webcpp.variants:

webcpp.variants page_program : page_program.cpp : <library>/webcpp/asio//asio ;

The build writes page_program.variants.json beside the JSPI artifact. Its jspi and asyncify objects each contain a script path relative to the manifest and the WebAssembly size in bytes. Serve the manifest, both scripts and their WebAssembly files with their relative layout intact.

The loader is include/webcpp/asio/webcpp-asio-loader.mjs, shipped with the headers. A page imports its load function and calls load('page_program.variants.json'). It detects JSPI by checking whether WebAssembly.Suspending is a function, chooses jspi when it is and asyncify otherwise, and reads the artifact path from the manifest. It resolves that path relative to the final manifest URL after any HTTP redirects, imports the script and awaits its default factory. A custom fetch that supplies no response URL uses the requested manifest URL. The result is {variant, module}.

supportsJspi(scope) permits detection in a supplied scope. pick(manifest, jspi) returns {variant, script} and rejects a missing script for the selected variant. load(manifestUrl, options) accepts an explicit jspi choice, module options passed to the factory, and replacements for fetch and importModule. Failed manifest requests report their URL and HTTP status; fetch, JSON, import and initialization failures propagate to the caller. A failed JSPI load does not silently retry Asyncify.

A relative manifest URL is resolved against the page URL, or against the loader module URL where no page location exists. Factory completion is variant-dependent: the current JSPI factory awaits main, while Asyncify can resolve before a suspended main finishes. An indefinitely running JSPI program therefore reports readiness through its module callbacks; an application observes its own completion signal. The loader test waits for the program’s output, within the driver’s timeout, rather than sleeping for an assumed duration.

The browser lane loads both variants under Node using a file reader for the manifest, and in headless Chrome over loopback HTTP. It exercises this actual page program:

int main() {
    webcpp::asio::io_context io;
    int ran = 0;
    for (int i = 0; i < 3; ++i) {
        webcpp::asio::post(io, [&ran] { ++ran; });
    }
    io.run();  // lint-run: the page's event loop, suspended into the browser's
    if (ran != 3) {
        std::puts("handler count mismatch");
        return 1;
    }
    std::puts("ran 3 handlers");
    return 0;
}

The same lane checks idle waits and animation callbacks under continuous ready work in Chrome. See Browser observations for its measurements and failure criteria.

The exit status

After a suspension, Asyncify loses the value main returns: a program whose exit status matters, under node, ends with std::exit; webcpp’s own tests end through webcpp::test::exit_status, and a test that does not fails (AGENTS.md chapter 9). asio’s tests pin both cases where node would read a failure as a pass, in each variant: a main that never finishes, and a main that suspended and then returns 1 without the helper.

TLS: build OpenSSL from source on native and WASI

For a program including <webcpp/asio/ssl.hpp>, add /webcpp/asio//openssl beside /webcpp/asio//asio in its target sources: exe app : app.cpp /webcpp/asio//asio /webcpp/asio//openssl ;. This forwards /webcpp/third_party//openssl, which builds OpenSSL 3.5.9 (commit 45e844fa2a14ec92d146bd8f5778ac130b6625fb) from the unmodified upstream submodule. No installed OpenSSL or OPENSSL_ROOT is used by this target.

In a Git checkout, initialize the source with git submodule update --init third_party/libs/openssl. A WebCPP source distribution already contains the required OpenSSL files and does not need Git. The build needs Python 3, Perl, Make, and the selected compiler toolchain; Git is also used to verify a source checkout. B2 invokes upstream Configure/Make and exports static libssl.a, libcrypto.a and their matching generated headers. Before Configure, it stages the distributable source files in a temporary directory and verifies their paths, file modes and content hashes against the pin. Missing, additional or altered files fail the build. Dot paths and pinned optional upstream repositories are omitted, just as in the source distribution. The temporary source directory also avoids upstream Makefiles’ restriction on source paths containing spaces. Different toolsets, optimization flags, exception settings and thread profiles use separate build directories. Effective C flags and compiler commands also identify separate archive/header directories. Flags retain normal B2 scope: dependency-specific cflags belong on the OpenSSL target, not only on its consumer. Independent concurrent B2 processes should use separate --build-dir directories. threading=single builds OpenSSL with no-threads; threading=multi enables its platform threading implementation. Native recipes support Clang/GCC on macOS/Linux and MSVC on Windows. MSVC uses upstream Configure and nmake, static archives and the B2 runtime/debug settings; the initial Windows recipe uses portable C without requiring NASM.

For a program built both natively and for the browser, use the condition below. It also selects OpenSSL for WASIp2/P3; browser builds retain the settings adapter:

project : requirements <conditional>@source-openssl ;

rule source-openssl ( properties * )
{
    if ! <toolset>emscripten in $(properties)
    {
        return <library>/webcpp/asio//openssl ;
    }
}

Do not use <toolset>!emscripten:<library>/webcpp/asio//openssl: that spelling silently fails to link OpenSSL in the tested B2 configuration.

Correct configuration errors as follows:

  • If ssl.hpp reports that OpenSSL is not linked, name the openssl target. Outside B2, define WEBCPP_ASIO_HAS_OPENSSL=1 and supply matching headers, libssl, libcrypto and platform dependencies yourself.

  • If the source checkout is missing, initialize the submodule with the command above. Tests requiring OpenSSL fail rather than silently skipping TLS.

  • If the target is named for the browser, select native or WASIp2/P3. The browser settings record does not implement TLS inside the Wasm module.

  • With WASIp3 threading=multi, use exception-handling=off with wasi-sdk 34.0: its cooperative sysroot does not contain the C++ exception runtime.

The built-in default and base providers are linked statically. Loading provider modules is disabled; this configuration is not a FIPS build. Both WASI profiles disable assembly, dynamic loading, QUIC, Unix-domain sockets and the OpenSSL thread pool. Native Clang/GCC builds retain upstream assembly optimizations; the initial MSVC recipe uses portable C. The recipe uses function and data sections plus platform dead stripping. A program has one OpenSSL provider. Native Trystero’s /webcpp/trystero//native target builds pinned static libdatachannel and its required nested sources against this same provider, so it can coexist with Asio and Beast. Such a program selects threading=multi and exceptions for Trystero’s worker-thread backend. Libsecp256k1 remains externally provisioned; OPENSSL_ROOT and LIBDATACHANNEL_ROOT do not select alternate providers.

The configured certificate directory is /etc/ssl. A source-built library does not install a system trust store or import the macOS keychain. Use the embedded factory in How-to: configure trusted certificate authorities for portable defaults, or explicitly load the intended CA file, set verify_peer, and verify the peer’s hostname on a raw context. WASI applications using a file must preopen its directory. Embedded authorities need no certificate filesystem access. Both require the needed TCP network capability; linking the library grants no runtime permission.

WASI seeding explicitly selects OpenSSL’s getrandom configuration, whose WASI implementation calls getentropy, then wasi-libc’s secure wasi:random/random.get-random-bytes host import. With Wasmtime’s default host configuration, the generator is seeded from the operating system. The host remains trusted: an embedder can replace its randomness provider. The tests verify that host entropy is requested and a reported entropy failure prevents random output and key generation; they do not prove cryptographic entropy quality or snapshot/restore safety. Reseed policy after restoring a seeded instance requires separate validation.

The reproducible native/WASIp3 test driver is python3 tools/openssl/test/run.py --fresh from the superproject. It needs Python with TLS 1.3 and an OpenSSL 3 command-line program only to create short-lived server fixtures. The client links the source-built library. WASMTIME selects the runtime executable; the recorded WASIp2/P3 checks use wasi-sdk 34.0 and Wasmtime 50.0.1. See Networking features for the target/variant matrix.

The recurring own lane b2 libs/asio/test/tls//tls-integration drives those TLS, embedded-CA and entropy fixtures on native and WASIp3 profiles. The Cobalt-owned libs/cobalt/test/tls//tls-integration lane checks SSL state and cancellation across the same profiles. The separate libs/cobalt/test/tls//tls lane drives the Cobalt fixtures on WASIp2 with each requested exception mode; see Build for WASIp2 for the complete command, including the ordinary Cobalt consumers. b2 libs/asio/test/tls//openssl-upstream is native only: it requests webcpp-openssl-tests=on, builds and runs upstream’s full alltests suite, then links a TLS consumer against those exact archives. The openssl-upstream-msvc-14.3 and openssl-upstream-msvc-14.5 aliases exercise that suite with the corresponding Windows CI toolsets. Ordinary consumers do not run that suite. The upstream harness is unavailable on WASI; the separate integration tests give narrower evidence and do not claim upstream-suite parity. A lane declaration is not evidence that the current candidate passed CI.

The library’s targets implement that distinction:

rule openssl-linked ( properties * )
{
    if [ webcpp-target.target-of $(properties) ] in native wasip2 wasip3
    {
        return <library>/webcpp/third_party//openssl
            <define>WEBCPP_ASIO_HAS_OPENSSL=1 ;
    }
}

# Refused on Emscripten: every source of a program built for emscripten
# that names it stops at the forced include, whose message says what to
# write. Quoted, as the Jamroot quotes Boost's directory, for a path that
# holds a space.
path-constant WEBCPP_ASIO_ROOT : . ;
alias openssl : : : : <conditional>@openssl-linked
    <toolset>emscripten:<cflags>"-include \"$(WEBCPP_ASIO_ROOT)/src/openssl_on_webassembly.hpp\""
    <toolset>emscripten:<cxxflags>"-include \"$(WEBCPP_ASIO_ROOT)/src/openssl_on_webassembly.hpp\"" ;

How-to: configure trusted certificate authorities

For a native or WASI client with portable trust defaults, include <webcpp/asio/tls_client_context.hpp> and link /webcpp/asio//tls. The target includes Asio, source-built OpenSSL and /webcpp/third_party//ca_certificates. No certificate file, environment setting, system trust store or network download is read by the factory. WASI needs no certificate directory preopen; a network connection still needs host permission.

This program prepares the context and checks errors without exceptions. With no arguments it uses the embedded roots. An optional argument supplies replacement PEM bytes, not a file path:

#include <cstdio>
#include <webcpp/asio/tls_client_context.hpp>
#include <webcpp/test/exit_status.hpp>

// main's standard signature requires char**, even though it does not modify argv.
// NOLINTNEXTLINE(misc-const-correctness)
int main(int argc, char** argv) {
    // An optional argument contains replacement PEM bytes, not a filename.
    // Keep the prepared context mutable for subsequent TLS stream construction.
    // NOLINTNEXTLINE(misc-const-correctness)
    auto prepared = argc == 1 ? webcpp::asio::make_tls_client_context()
                              : webcpp::asio::make_tls_client_context(argv[1]);
    if (!prepared) {
        const auto message = prepared.error().message();
        (void)std::fprintf(stderr, "%s\n", message.c_str());
        return webcpp::test::exit_status(1);
    }
    // Pass *prepared to TLS streams and keep it alive while those streams exist.
    std::puts(argc == 1 ? "TLS client ready: embedded authorities"
                        : "TLS client ready: replacement authorities");
    return webcpp::test::exit_status(0);
}

The default invocation prints:

TLS client ready: embedded authorities

Use the resulting context when constructing TLS streams and keep it alive while they exist. The factory enables verify_peer and requires TLS 1.2 or newer. Configure ssl::host_name_verification for the expected hostname and set SNI on each connection. A trusted issuer alone does not establish the intended hostname.

The overload taking std::string_view replaces the complete trust set. It does not append private authorities to public roots. Supply one or more PEM CA certificates separated by whitespace. Empty input, malformed certificates, non-CA certificates, and trailing non-whitespace data return an error without a usable context. The certificates are copied into the context; the input may then be released. Initialization failures are errors as values too, with or without exceptions. OpenSSL owns its allocations and does not use an Asio allocator. On Emscripten the helper returns unsupported_target: browser TLS and its trust policy remain under the browser’s control.

Updating the embedded snapshot

The source is the Mozilla CA export from curl, preserved in third_party/ca_certificates/cacert.pem with its MPL-2.0 license. The adjacent manifest records the source URL, date, SHA-256 and each certificate’s DER fingerprint. The initial snapshot is dated 2026-09-25 and contains 121 CAs. Keep its license and corresponding PEM source available when redistributing it.

Choose a published date from the curl CA Extract page. From the superproject root:

python3 tools/ca_certificates/update.py --date 2026-09-25
python3 tools/test/ca_certificates_test.py
python3 tools/test/ca_certificates_b2_test.py
python3 tools/ca_certificates/run.py --fresh

The updater downloads through verified HTTPS, checks the published SHA-256, validates every certificate and reports added/removed fingerprints. Review the trust changes and version the PEM and manifest together. An older date is rejected. Use --output DIRECTORY to stage a candidate separately, or --source-file PATH --sha256 DIGEST for an independently authenticated offline copy. A checksum detects a changed artifact; it is not an independent publisher signature. Normal builds use the pinned artifact without downloading anything.

Rebuild and redeploy applications after changing the snapshot. Existing binaries retain their embedded roots. The updater does not schedule downloads or alter running programs. The build rejects a missing or hash-mismatched snapshot. If an update was interrupted between replacing its two files, restore both from Git and repeat it. Run only one updater per output directory.

Using installed headers

b2 install --prefix=DIR includes the generated webcpp/asio/detail/ca_certificates.hpp under DIR/include/. Its private namespace is webcpp::asio::detail::ca_certificates. The matching PEM source, manifest and MPL notices are under DIR/include/webcpp/ca_certificates/. The CA package is generated locally without compiling OpenSSL. A consumer of the installed TLS header must still configure Boost, define WEBCPP_ASIO_HAS_OPENSSL=1 and link compatible OpenSSL headers and archives. Installation does not package the Cobalt runner or dependency archives.

What portable trust does and does not mean

The PEM export omits some additional constraints enforced by Firefox. It does not reproduce the complete browser policy, consult the host’s private roots or automatically fetch revocation information. Explicit replacement lets an application choose a narrower or organizational trust set. Native system trust integration and automatic runtime updates are separate features.

Local tests cover real TLS 1.2/1.3 connections, wrong hostnames, an unrelated CA, and rejection of a private test CA by the default public bundle. They also check complete replacement and invalid input. The matrix covers native macOS single/multi with exceptions on/off, WASIp2/P3 single with exceptions on/off, and WASIp3 cooperative threads with exceptions off under SDK 34. The WASIp3 client runs without certificate filesystem grants. Tests use a fresh local test CA; they do not depend on a public website’s availability.

How-to: consume the shipped implementation

Include the webcpp/asio/ headers and use webcpp::asio. Native equivalents, including io_context, timers, sockets and executors, are the actual Boost.Asio types. The browser’s turn-control members are WebCPP extensions and are not members of the native context. WebAssembly selects a versioned implementation shipped with the library. Header selection is explicit in config.hpp; it does not depend on B2 applying patches or putting replacement Boost headers first.

Use matching Boost 1.92 dependencies with this source snapshot. All translation units and compiled bridge sources must use the same target, exception mode and thread ABI. A config macro cannot supply a runtime capability or change the compiler’s ABI.

The inherited system executor’s query(execution::context), query(execution::occupancy) and context() are noexcept. If their first use cannot create the global system context, initialization failure terminates the process, including with exceptions enabled. The shipped Wasm implementation makes that fatal boundary explicit; it does not report an allocation failure as a successful query. Use an explicitly constructed io_context when application code must handle context-construction failure.

sources.json lists runtime sources and private include directories per target. B2’s src/sources.jam is generated from that same inventory. Neither consumer runs the maintainer importer or creates a replacement Boost include directory.

Profile Additional source and toolchain requirements

Native

Boost.Asio headers and the platform’s normal thread/socket libraries.

WASIp2

src/wasip2/pollable.cpp; pinned SDK ABI declarations in src/wasip2/wasi-libc; single-thread SDK profile.

WASIp3

src/wasip3/waitable.cpp; pinned SDK ABI declarations in src/wasip3/wasi-libc; matching single or cooperative-thread sysroot.

Emscripten

src/browser_src.cpp linked as an object; embind, stack exports and the selected JSPI or Asyncify link flags.

Run the corresponding src/wasip2/verify.py or src/wasip3/verify.py with --sdk /path/to/wasi-sdk before compiling an SDK bridge. Those private ABI declarations require the pinned SDK; copying them does not make another SDK compatible.

The superproject’s tools/test/fixtures/portable-network/CMakeLists.txt is an out-of-tree consumer recipe. The accompanying tools/test/portable_network_distribution.py creates a source archive with a SHA-256 inventory, deletes its staging inputs, extracts it into a path with spaces and builds without Git, B2, cached overlays or checkout include paths. The archive also retains each library’s upstream/ provenance: original revision and hashes, resulting hashes, correction bundles and maintainer inputs. These are audit records, not consumer build steps. Compiler dependency files verify the actual sources and headers against the archive, explicit dependencies and the selected compiler’s declared SDK paths. --evidence-dir <directory> preserves the archive and compiler receipt. The consumers exercise timers, TCP/UDP, DNS, HTTP/WebSocket and Cobalt timers. The browser variant tests a Promise, timer and HTTP parser under Node; actual browser and worker tests remain separate.

For Emscripten, use the SDK’s emar and emranlib when making static libraries. Keep the browser bridge object in the final link: its JavaScript import metadata must not be discarded as an unused archive member. Use the compiler and linker flags shown by the consumer recipe rather than treating JSPI or Asyncify as a preprocessor-only option.

Optional TLS additionally requires matching OpenSSL headers and libssl/libcrypto, the selected CA resource, and WEBCPP_ASIO_HAS_OPENSSL=1. It is not pulled into plain Asio. The browser instead uses the browser’s HTTPS/WSS trust policy. The WASI provider also requires the wasi-emulated-getpid, wasi-emulated-signal, wasi-emulated-process-clocks and wasi-emulated-mman libraries after the crypto archive, as shown in the consumer recipe.

Customize completion tokens and associated traits

Write qualified specializations at global scope, using the public webcpp::asio::async_result or webcpp::asio::associated_executor name. These resolve to the template of the selected backend, including native Boost. Do not open a separate namespace containing a new template with the same name. The completion-handler macro is WEBCPP_ASIO_HANDLER_TYPE, from config.hpp; include async_result.hpp before expanding it.

test/distribution/customizations.hpp supplies a complete token and associated executor specialization. Its consumer registers a timer in one translation unit and cancels it from another that also includes Beast and Cobalt. The direct compiler and CMake recipes build those same files with uniform configuration.

Build for WASIp2

Use /webcpp/asio//asio with toolset=clang-wasip2 and threading=single. This profile uses Boost 1.92, wasi-sdk 34.0 and Wasmtime 50.0.1. Both exception modes are supported for the core, timers, TCP/UDP, asynchronous forward DNS, Cobalt and source-built OpenSSL. Multiple application threads remain unavailable with the pinned SDK profile.

Configure the compiler using the project’s wasi-sdk user-configuration example. Then run the local consumers from the superproject root:

b2 -a toolset=clang-wasip2 variant=release threading=single \
  exception-handling=on,off testing.launcher=tools/boost/asio-wasip2/run.sh \
  libs/asio/test/wasip2 libs/asio/test/capability_wasi
b2 -a toolset=clang-wasip2 variant=release exception-handling=on,off \
  libs/asio/test/wasip2//supplied-stream libs/asio/test/wasip2//scheduler-idle

Add /webcpp/cobalt//cobalt for Cobalt, /webcpp/asio//tls for OpenSSL with embedded or replacement trust roots, or /webcpp/cobalt//cobalt_ssl for Cobalt’s corrected SSL wrapper. These targets share the same source-built provider as native and WASIp3 programs. Run their real peer, trust, transfer/shutdown and cancellation consumers with:

b2 -a toolset=clang-wasip2 variant=release exception-handling=on,off \
  testing.launcher=tools/boost/asio-wasip2/run.sh \
  libs/cobalt/test/wasip2 libs/cobalt/test/tls//tls

The first command exercises timers, the run/poll family, TCP and UDP exchanges, coroutines, forward name resolution and pollable readiness. The supplied-stream lane keeps standard input open without sending data; its timer must still cancel a pending read. Each consumer reports a passing result. The network launcher explicitly grants socket access and IP name lookup; production hosts should grant only the application’s required capabilities.

The idle driver uses an external watchdog and a Wasmtime fuel budget. A context with a live work guard must remain asleep, including before a reactor is created. The write-permit consumers exercise a real output with a controlled 64-bit quota and cancellation against a deliberately non-ready native pollable. Those fixtures test the adapter’s boundary handling; they do not measure every host implementation.

How readiness reaches the executor

WASIp2 provides TCP, UDP, name-resolution streams, monotonic clocks and resources that expose readiness through wasi:io/poll. The port retains Boost.Asio’s select reactor. wasi-libc gathers socket pollables and timer deadlines into one host wait. No worker thread, fixed-interval DNS scan or browser turn budget is introduced. The P2 single-thread profile omits Asio’s pipe-based cross-thread interrupter: this libc has no P2 pipe implementation, and the profile cannot receive work from another application thread. An idle scheduler without a reactor waits on a maximum-instant monotonic-clock pollable. It does not submit an empty poll list, which WASIp2 rejects, or spin.

A DNS address stream is not a POSIX descriptor. A small compiled bridge registers its borrowed pollable with wasi-libc’s descriptor table so the same reactor can wait for sockets, DNS and timers together. That registration API is private to wasi-libc. The build verifies SDK 34.0, libc revision 2e6fb9d8ee0c and the exact copied declaration hashes. Changing the SDK requires revalidating this bridge; the build must not silently use an unknown ABI. The upstream installation is never modified.

Resolver contract

async_resolve starts the native lookup through the executor. A deferred token does not start DNS until initiated. The handler never runs inside initiation, uses its associated executor, and receives an error value on failure. Resolver cancellation and per-operation cancellation work before and after registration. Destroying a resolver cancels pending lookups; destroying its context abandons handlers and releases the owned resources.

Numeric host parsing and the libc service-name table require no host DNS wait. The host supplies forward lookup addresses; host capabilities govern access. canonical_name, v4_mapped and all_matching are explicitly unsupported by this adapter and complete with operation_not_supported. Asynchronous reverse lookup also remains unsupported. address_configured uses libc’s numeric family checks. Loopback tests establish local resolution, not access to every external DNS server.

Operation storage and copied input/endpoint scratch storage use the associated handler allocator. Resolver ownership uses the context allocator. The public Boost result container, libc address parsing and descriptor-table storage retain their upstream allocation behavior; this is not a zero-global-allocation promise.

Use a supplied CLI byte stream

webcpp::asio::wasi::stdio_stream implements partial synchronous and asynchronous reads/writes over WASIp2 CLI resources. Its asynchronous waits use the same reactor, preserve completion-token associations and support cancellation. Only one read and one write may be pending per stream. Keep buffer storage alive until completion. The stream owns resource handles but does not close libc’s descriptors 0 and 1. Cancellation aborts pending operations; subsequent operations remain usable. Closing or destroying the stream cancels pending operations and prevents new I/O.

The Beast supplied-channel client and server run real WebSocket upgrade, text, fragmented binary transfer, ping/pong and close over this adapter, in both exception modes. They need no TCP socket grant. These channels do not provide Unix socket names, descriptor passing, peer credentials or wasi:http WebSocket upgrades.

Writes request a WASI flush before the protocol switches to reading. Readiness cannot preempt an import that the host itself implements with blocking I/O. In particular, Wasmtime CLI stdout can block when its OS pipe fills. A paused consumer must resume draining before the component can observe cancellation. A strict cancellation deadline requires a host/channel whose write imports remain nonblocking.

Unsupported operations and build profiles

threading=multi is rejected: SDK 34.0 has no supported P2 pthread runtime profile. POSIX signals, Unix-domain sockets and serial ports are absent from the host interfaces used here. Use the capability guards in Require a capability at compile time for compiler-visible requirements. Cobalt’s known no-EH pending-task move issue remains an upstream limitation, as on native and P3; see Exceptions and error handling.

Unsupported socket operations retain error-code overloads. Tested examples include linger and at_mark, which return operation_not_supported. UDP send_to and connected send gather multiple buffers into one datagram; receive scatters one datagram across the destination buffers. Asynchronous forms retain handler allocation and cancellation. TCP retains partial I/O semantics. Numeric IPv6 scope identifiers work; named interfaces are rejected with invalid_argument. Host permission denial is a runtime error, distinct from an unsupported build profile. Prefer error-code/completion-handler paths for recovery, especially when exception handling is disabled.

Build and test a WASIp3 program

This how-to uses the same timer example as the native tutorial. The port also provides TCP/UDP through its selected socket backend. Read Target and variant capabilities before choosing a profile; it records the restrictions that still differ from native.

Prerequisites

Use Boost 1.92.0, wasi-sdk 34.0 and Wasmtime 50.0.1 for the configuration verified here. The distributed Wasm backend records exact upstream inputs and corrections. Updating it requires rerunning the maintainer importer and regression tests; an application build uses the sources already shipped in the library. WASIp3 and cooperative threads require runtime support; the previously installed Wasmtime 47.0.3 could not load the SDK’s cooperative-thread component.

Register clang-wasip3 in user-config.jam as shown by the superproject’s WASI setup. Put the SDK in .local/wasi-sdk, or supply -sWASI_SDK=/path/to/wasi-sdk when choosing the cooperative profile. It must be the same SDK as the compiler registered for this toolset. Put the tested Wasmtime binary on PATH.

/webcpp/asio//asio selects the shipped WebCPP headers and compiles src/wasip3/waitable.cpp. It validates the SDK’s private descriptor ABI before building that bridge. Neither B2 nor another consumer build patches Boost or inserts a replacement Boost include tree. See How-to: consume the shipped implementation for the equivalent source contract outside B2.

Run without threads

From the superproject root, build and check the existing timer example:

b2 -a toolset=clang-wasip3 variant=release threading=single \
  exception-handling=on \
  testing.launcher=tools/boost/asio-wasip3/run.sh \
  libs/asio/example//asio_quick_start.output

The example’s source is in Tutorial: your first asynchronous program. Expected output:

posted
timer fired
run returned 2 handlers

Repeat with exception-handling=off to use the single-thread runtime without C++ exceptions. The library keeps Boost’s callback and error-code interfaces. No JSPI or Asyncify flags are needed.

Run with cooperative threads

b2 -a toolset=clang-wasip3 variant=release threading=multi \
  exception-handling=off \
  testing.launcher=tools/boost/asio-wasip3/run.sh \
  libs/asio/test//wasi_core_threads

The build selects experimental-coop-threads as its sysroot and adds -pthread consistently to compilation and linking. It uses that sysroot’s C++ configuration and the matching SDK’s common libc++ headers. This is an experimental SDK profile, not a promise of CPU parallelism. In the tested SDK, requesting exceptions in this profile fails at configuration with a message naming the missing runtime.

The test launcher is for local and CI verification: it enables WASIp3 asynchronous components and cooperative-thread support, grants host network and name-lookup access for the loopback tests, and bounds each guest’s execution to 600 seconds. The global lane also runs large finite document and Unicode workloads. Set WEBCPP_WASIP3_TEST_TIMEOUT to a positive integer number of seconds to choose another bound, for example WEBCPP_WASIP3_TEST_TIMEOUT=15 for focused loopback tests. Invalid or zero bounds fail before launch. Enabling a runtime feature does not create threads in a single-thread binary. Production applications should choose their own timeout and network capabilities.

Reproduce the local verification

Run the declared WASIp3 tests and examples with -a, then repeat for each supported profile from Build configurations:

b2 -a toolset=clang-wasip3 variant=release threading=single \
  exception-handling=on \
  testing.launcher=tools/boost/asio-wasip3/run.sh \
  libs/asio/test libs/asio/example

b2 -a toolset=clang-wasip3 variant=release threading=single \
  exception-handling=off \
  testing.launcher=tools/boost/asio-wasip3/run.sh \
  libs/asio/test libs/asio/example

b2 -a toolset=clang-wasip3 variant=release threading=multi \
  exception-handling=off \
  testing.launcher=tools/boost/asio-wasip3/run.sh \
  libs/asio/test libs/asio/test//wasi_core_threads libs/asio/example

python3 libs/asio/src/wasip3/verify.py --sdk .local/wasi-sdk
python3 tools/test/asio_wasip3_test.py
python3 tools/test/cobalt_wasip3_test.py

wasi_core exchanges real TCP and UDP traffic over ephemeral IPv4 loopback ports, tests timer and socket cancellation, scatter/gather TCP, and TCP EOF. wasi_core_threads adds a cross-thread post into a reactor with a pending timer and two runners sharing a context. wasi_contract checks empty datagrams, vectored UDP receive with datagram truncation, IPv6 numeric scopes, socket option errors and resolver behavior. wasi_coroutine waits for a timer using Boost.Asio’s co_spawn and awaitable with result-based error handling. The existing run-family and timer tests also run on WASIp3. wasi_udp_gather and capability_wasi/datagrams check synchronous and asynchronous multi-buffer sends and receives, including complete sequences beyond 64 buffers, allocation routing, empty datagrams, oversized input and release of storage before completion.

The SDK verifier checks the private ABI snapshot. The maintainer importers check source hashes, and external consumers use a source snapshot with spaces in its path and no cached replacement Boost headers. Unsupported SDK profiles fail with diagnostics. Native controls use the same runtime test sources. These are local commands; none starts a CI job.

Build a Cobalt application

Use <library>/webcpp/cobalt//cobalt in the application’s B2 requirements, webcpp/cobalt/ headers and webcpp::cobalt names. The application supplies co_main; the separately compiled runner omits unsupported process signals. Cobalt’s explicit source inventory also supports other build systems. The old Asio target is a forwarding alias, not a second implementation.

Run the existing Cobalt timer example:

b2 -a toolset=clang-wasip3 variant=release threading=single \
  exception-handling=on \
  testing.launcher=tools/boost/asio-wasip3/run.sh \
  libs/cobalt/example//asio_cobalt.output

The expected output and complete source are in the Cobalt tutorial.

Repeat with exception-handling=off, or with threading=multi and exception-handling=off for the cooperative runtime. The latter can also run the explicit libs/cobalt/test//cobalt_thread test. The ordinary test target includes cobalt_wasi, cobalt_network_exceptions_on/off and cobalt_io; they cover the runner, both timer APIs, Asio TCP/UDP through use_op, Cobalt’s own IP socket wrappers, refused TCP connections, TCP/UDP cancellation, EOF and result-based resolver behavior.

The libs/cobalt/test//cobalt_wasip3 lane checks successful and unsuccessful command completion with an exact-status driver. Put Wasmtime 50.0.1 on PATH, or set WASMTIME to its executable for that driver. The SDK maps nonzero coroutine returns to host status 1.

For TLS, add /webcpp/asio//tls and await Asio SSL operations with webcpp::cobalt::use_op. The following public-target drivers check TLS 1.2/1.3, trusted and rejected identities, malformed CA data, transfer cancellation and clean, failed and cancelled shutdown:

b2 -a toolset=clang-wasip3 variant=release libs/cobalt/test/tls//tls

The WASI client needs network capabilities but no CA filesystem preopen. To use Cobalt’s own io::ssl::stream, link the optional /webcpp/cobalt//cobalt_ssl target. Its shipped implementation, trust configuration and local test commands are described in Use the corrected SSL stream.

The underlying platform contracts are documented by wasi-sdk’s cooperative-thread guide and the Wasmtime release used here.

The run family

The io_context’s run, run_one, run_for, run_until, run_one_for and run_one_until keep Boost.Asio’s meaning on every target: run returns when the io_context is out of work or stopped, run_one after one handler, run_for and run_until after their deadline is observed, and each returns the number of handlers it ran. poll and poll_one retain the selected backend’s behavior. Natively the context and all its operations are Boost’s own types; there is no browser turn option.

On Emscripten the six hide the shipped backend’s operations. run composes that backend’s calls and repeats four steps:

  1. Call poll_one until it returns 0 or the current turn has run max_handlers_per_turn handlers, including handlers from step 4.

  2. If the io_context is stopped, return.

  3. If the turn reached the limit, yield to the browser, reset its count and go to step 1.

  4. Otherwise call the backend’s run_one, which suspends in the reactor’s select until a timer, a post or I/O makes a handler ready, and runs it. If it ran none, the io_context being stopped or out of work, return; else count its handler in the current turn and go to step 1.

run_for and run_until are the same composition with the backend’s run_one_until in step 4. Like Boost’s, they check their deadline before each handler, so that a deadline already passed runs nothing, and they return once it has passed, even when every turn reaches the limit. A running handler cannot be interrupted, and host scheduling can delay resumption beyond the deadline. run_one is step 4 alone, and run_one_for and run_one_until are the backend’s, each running one handler at most. Code that calls run through a reference to the shipped backend’s base context gets the backend’s run, which suspends as well but has no limit.

A turn at a time

Boost’s run runs handlers until none is ready, those posted meanwhile included, and a select whose timeout is zero suspends only to a microtask, which never lets the page render. Measured with Emscripten 6.0.11, a handler that posts itself ran 300,000 times under Boost’s run before a JavaScript setTimeout(0) ran, in either suspension variant. Boost’s run is not virtual and cannot be told to yield, hence the composition.

The yield is a suspension, an EM_ASYNC_JS import whose promise a MessageChannel message resolves: a macrotask rather than only a microtask, giving the browser an opportunity to render, run timers and deliver events. It does not guarantee that any particular work happens before the next turn. MessageChannel exists in every browser and in node.

A turn runs at most max_handlers_per_turn handlers, and the run family yields to the browser after each turn that reaches it. Both ready handlers and step 4’s handler consume the same turn budget. A wait does not reset it: a short timer can make the reactor suspend only to microtasks, which cannot deliver browser events or worker proxy messages. The budget resets after the explicit macrotask yield, even when an earlier wait happened to let browser work run. The option is 100 by default. Historically, with a limit of 1000 and Emscripten 6.0.11, the setTimeout(0) above ran after 1,000 handlers under JSPI and 999 under Asyncify, against 300,000 without the limit, and run still ran every handler. It is given at construction, io_context io(io_context_options{.max_handlers_per_turn = 250}), or later with io.max_handlers_per_turn(250); 0 is taken as 1. A stop made by the handler that reaches the limit returns at once, without a yield first. Held by turn_limit, which counts the yields of a handler that posts itself and of a chain of timer completions: one after every max_handlers_per_turn handlers under run and run_for, never more handlers between two, and none under the backend’s base run; and a JavaScript setTimeout(0) runs at a yield, seen by the first handler of a turn. And by run_family, in each variant.

Configure the build’s default turn limit

WEBCPP_ASIO_DEFAULT_MAX_HANDLERS_PER_TURN in config.hpp supplies the initial value of io_context_options::max_handlers_per_turn. It defaults to 100 and can be replaced by a compiler definition, for example to use 1000:

-DWEBCPP_ASIO_DEFAULT_MAX_HANDLERS_PER_TURN=1000

For b2, pass the definition on the command line for the complete build:

b2 -a --build-dir=bin/asio-limit-1000 toolset=emscripten \
    define=WEBCPP_ASIO_DEFAULT_MAX_HANDLERS_PER_TURN=1000 \
    libs/cobalt/example//asio_cobalt.output

Use the same value in every translation unit that uses asio and rebuild all of them when changing it. In particular, Cobalt’s runner is compiled separately: a definition in an application source file alone cannot configure an existing runner archive. A separate build directory avoids reusing outputs built with another definition. Do not mix differently configured objects in one program.

An explicit option at construction or a later max_handlers_per_turn(n) call overrides this build default for that context. Zero is normalized to one; negative build defaults are rejected. Native scheduling is unchanged.

The value 100 is a configurable scheduling policy, not a measured optimum or a time budget. Smaller values offer more frequent yields under continuous ready work, with more suspension and scheduling overhead. A single expensive handler can still block the thread. The original browser measurements used small self-posting handlers and checked turn duration, not isolated yield cost. The later Release benchmark measures yield latency separately. See From the original 1,000 default to 100 for the default’s origin and validation, and Relating the limit to an application’s cost budget for the cost model and its limits.

Who may call it

The run family is called on the stack of main, or on the stack of another export the program lists for suspension: in -sJSPI_EXPORTS under JSPI, whose call then returns a promise, and called with ccall(..., {async: true}) under Asyncify. Anywhere else its first suspension fails: under JSPI it throws a SuspendError, and under Asyncify it starts an unwind that corrupts a suspended main. Nothing calls run, poll or dispatch from a JavaScript event: while run is suspended, an event sees running_in_this_thread() true, because the frame run pushed stays on the stack, and a dispatch there runs its handler inside the event, on the wrong stack. asio’s bridge only posts. Nor does a program block the page’s thread without suspending, in a busy loop or a blocking system call.

On emscripten, a run family call made while another runs, or while the bridge delivers a browser event, asserts and returns 0 having run nothing. The io_context keeps a flag while one of its six members runs, and the bridge counts the deliveries in progress. A call while either is set (a nested call from a handler, a run from a JavaScript event while run waits, a run from a registration’s deliver) is a precondition violation, reported by BOOST_ASSERT_MSG, and with assertions off it is still refused. The run around a refused call goes on, still flagged. A handler’s C++ exception that leaves run clears the flag on its way, so that the program’s restart(); run(); after its catch is no nested call. A JavaScript error is another matter (see a JavaScript error out of a handler): where it skips destructors it leaves the flag set, as it leaves Boost’s own state broken, and the context refuses every later call. Each member admits its call once, before any work, and then runs only private code or Boost’s, never another member of the family, whose admission would refuse the call its caller flagged.

Detection is of a call of this run family on the context whose flag or bridge is set. Four calls go undetected: a call from an export of the program’s own that is not listed for suspension, which nothing tells from main until its first suspension fails; a call through a reference to the shipped backend’s base context, which reaches Boost’s own run; poll, poll_one and dispatch, which are Boost’s and no member of the run family, called from a JavaScript event; and a call on another io_context, whose flag and bridge are its own, from a handler or a delivery of this one.

Held by detection, in each variant, with and without exceptions, with an assertion handler counting the assertions and with assertions off: a nested run_for, run_one and the other timed forms nested one after another in a single run, a run from a JavaScript setTimeout while run waits, a run from a delivery while no run is active and a handler is ready, which it leaves for the next run, run again after a C++ exception left it, every timed form over several turns and on a timer alone with no assertion, and the poll of a context with no reactor from a handler. And by flag_scope, the flag’s scope, which puts back the value it found.

A library never calls the run family: it is given an executor. webcpp’s lint refuses a call of run, run_one or run_for on an io_context whose line does not say why after lint-run:, and a program’s own says it, as io.run(); // lint-run: the program's event loop, suspended into the browser's.

xactor’s asio_driver drains an io_context of its own with poll. That context makes no timer and no socket, so it has no reactor: its poll never reaches select and never suspends, and calling it from a handler of the program’s io_context is safe in either variant.

Exceptions

A handler’s exception propagates out of run, as Boost’s, on both variants. Handlers run on the stack of main, inside the run family call, so that a C++ exception a handler throws leaves run, clearing the run family’s flag on its way, and reaches the program’s catch, after any number of suspensions and yields. A suspension keeps what encloses it: a try around run catches what a handler throws after run suspended, and a run called inside a catch block suspends and resumes there. Each variant compiles with the exception model it can suspend through (see the two suspension variants): WebAssembly exceptions under JSPI, and JavaScript-based exceptions under Asyncify, which traps when it suspends inside a catch block of WebAssembly exceptions. A JavaScript error out of a handler is caught by no C++ catch, and what it leaves depends on the build (see a JavaScript error out of a handler).

Held by exceptions, natively and in each variant, built with exceptions whatever the build asks: a try that encloses a run which suspends in the reactor’s wait catches nothing, a run suspends inside a catch block and resumes there, a handler’s exception thrown after run suspended reaches a catch in main, and the next run after it runs its handler, no nested call, and so does one thrown after run yielded twice to the browser, 2,000 handlers having filled two turns of the default limit.

Before run, and after main

On emscripten, handlers run only on the stack of a run family call, as natively: work posted before run is called waits for it, and a browser event that arrives while no run is active is posted and waits for the next one. Held by reactor, where work posted before run runs only inside it, and a post made from a JavaScript setTimeout wakes a suspended run.

As natively, run returns when no operation is pending, even with a connection open: a WebSocket with no pending read does not keep run alive, and its messages queue. After main returns, the runtime stays alive, since Emscripten keeps it by default, events keep being posted, and nothing runs them unless an export listed for suspension calls the run family again.

How to configure the turn limit

When ready work repeatedly posts more work, set the limit on the context that runs it. This program requests turns of 250 handlers and posts a finite chain of 5,000 pieces of work:

#include <webcpp/asio/io_context.hpp>

#include <webcpp/test/exit_status.hpp>

#include <webcpp/asio/post.hpp>

#include <cstddef>
#include <cstdio>
#include <functional>

namespace asio = webcpp::asio;

namespace {

/** The context and remaining work of a finite chain of posted handlers. */
struct work {
    asio::io_context& io;
    std::size_t remaining;
};

/** Runs one piece of work and schedules the next without calling it inline. */
void next(work* state) {
    if (--state->remaining != 0) {
        webcpp::asio::post(state->io, std::bind_front(&next, state));
    }
}

}  // namespace

int main() {
    asio::io_context io(asio::io_context_options{.max_handlers_per_turn = 250});
    work state{.io = io, .remaining = 5000};
    webcpp::asio::post(io, std::bind_front(&next, &state));
    std::printf("max_handlers_per_turn: %zu\n", io.max_handlers_per_turn());
    const auto handlers = io.run();  // lint-run: main owns the program's event loop
    std::printf("handlers run: %zu\n", handlers);
    return webcpp::test::exit_status(0);
}

Run it from the superproject root:

b2 toolset=emscripten libs/asio/example//asio_turn_limit.output
max_handlers_per_turn: 250
handlers run: 5000

Keep the state alive until run returns. Each handler posts the next one instead of calling it inline, so the context can yield between turns. Natively the same program prints the same output, but the option does not change Boost’s scheduling. Change the limit to trade handler throughput against opportunities for the browser to process other work. A handler that itself blocks for a long time still blocks the page; the option does not impose a time budget on individual handlers. The measured browser checks are described in Browser observations.

Yield measurements of the shipped implementation

This fresh local experiment began at 2026-11-07T04:21:58.914Z using HeadlessChrome/156.0.8078.4. It measures the current shipped Asio backend with Release -O3, independently of the historical October experiment below. Both JavaScript and Wasm artifacts and the implementation source are fingerprinted before execution. Builds and conformance tests from this session completed before sampling; other user and OS activity is not controlled.

The interval is the handoff to the browser and return to C++, excluding the callback batch. It includes the dispatcher return/reentry boundary. C++ and JavaScript monotonic clocks share the browser time origin; wall-clock bracket checks and pure-JavaScript controls test the measurement. The default remains 100 handlers per turn. This is a scheduling policy, not a time budget or a guarantee of rendering/input latency.

Variant Handlers per turn Median of mean gaps (us) Median of p95 gaps (us) Derived cost per handler (ns)

asyncify

direct yield

4.763

10.000

n/a

asyncify

1

5.240

10.000

5239.95

asyncify

10

5.037

10.000

503.75

asyncify

100

5.527

10.000

55.27

asyncify

1000

5.669

10.000

5.67

asyncify

5000

6.323

10.000

1.26

asyncify

10000

6.875

10.000

0.69

jspi

direct yield

4.103

10.000

n/a

jspi

1

4.520

10.000

4519.65

jspi

10

4.214

10.000

421.45

jspi

100

4.355

10.000

43.55

jspi

1000

4.434

10.000

4.43

jspi

5000

4.731

10.000

0.95

jspi

10000

4.976

10.000

0.50

All 442 cases passed validation: 970,139,132 operations and 9,429,856 timestamp pairs. Seven primary repetitions and three secondary-control repetitions are retained. Percentiles in the table are medians of per-run percentiles, not a pooled tail guarantee. Dividing the measured gap by the turn limit is an amortized estimate; it does not measure the callback work itself.

Additional groups cover no exceptions, ordinary nonisolated pages, tracing, clocks, synchronous language crossings and arithmetic work. A zero clock tick does not prove zero cost. The complete distributions, ranges and paired controls remain in runs.csv and summary.json.

bench/yield/results/2026-11-07 retains the generated results, build/environment metadata and raw evidence archive with its SHA-256 file. bench/yield/README.adoc gives the reproduction commands. This is a headless otherwise idle-page experiment, not a loaded application or remote CI run.

2026-11-07T01:31:41.990323 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ 1 10 100 1,000 5,000 10,000 Handlers per turn (tested settings) 0 1 2 3 4 5 6 7 Microseconds per yield gap 4.52 4.21 4.36 4.43 4.73 4.98 5.24 5.04 5.53 5.67 6.32 6.87 Measured boundary gap: excludes callback batch work JSPI ASYNCIFY 1 10 100 1,000 5,000 10,000 Handlers per turn (tested settings) 1 0 0 1 0 1 1 0 2 1 0 3 Nanoseconds per callback (log scale) Derived scheduling cost per callback JSPI ASYNCIFY Yield latency and turn limits Release -O3 | Exceptions enabled | Isolated page | Seven repetitions per setting Dots: median of per-run means. Error bars: range of run means, not confidence intervals. Amortization = measured gap / turn limit. Gaps include small dispatcher return/reentry costs.
Figure 1. Yield gap and derived amortization
2026-11-07T01:31:42.334584 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ 0 1 2 3 4 5 6 7 Microseconds per round trip JSPI / EH on JSPI / EH on / traced ASYNCIFY / EH on ASYNCIFY / EH on / traced JSPI / EH off JSPI / EH off / traced ASYNCIFY / EH off ASYNCIFY / EH off / traced JSPI / ordinary page JSPI / ordinary page / traced ASYNCIFY / ordinary page ASYNCIFY / ordinary page / traced JavaScript only JavaScript only / traced 4.10 4.94 4.76 5.63 4.09 4.92 4.60 5.44 4.17 4.93 4.74 5.71 3.94 4.79 Direct latency: median of run means 0 1 2 3 4 5 6 Microseconds, arithmetic means of traced runs JSPI / EH on ASYNCIFY / EH on JSPI / EH off ASYNCIFY / EH off JSPI / ordinary page ASYNCIFY / ordinary page JavaScript only 4.97 5.63 4.97 5.43 4.93 5.69 4.80 Instrumented phases: means add to the total Caller entry Channel construction Handler + observer setup postMessage Post return to delivery Close port + resolve Resume Direct round trips and observed phases Same Promise / MessageChannel mechanism | Untraced and traced measurements kept separate Primary and JS-only controls: 7 runs; EH-off and ordinary-page controls: 3 runs. The observer adds cost. Post-to-delivery includes suspension and scheduling, not pure queue wait. Sub-resolution phase values are aggregate estimates; individual clock steps remain quantized.
Figure 2. Direct controls and traced phases
2026-11-07T01:31:42.709402 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ 1 10 100 1,000 5,000 10,000 Handlers per turn (tested settings) 0 1 2 3 4 5 6 Microseconds (median of run means) JSPI: measured yield boundary gaps EH on, untraced EH off, untraced 64 source-level LCG updates EH on, traced 1 10 100 1,000 5,000 10,000 Handlers per turn (tested settings) 0 1 2 3 4 5 6 7 Microseconds (median of run means) ASYNCIFY: measured yield boundary gaps EH on, untraced EH off, untraced 64 source-level LCG updates EH on, traced 1 10 100 1,000 5,000 10,000 Handlers per turn (tested settings) 1 0 0 1 0 1 Whole-run ratio (log scale) JSPI: elapsed-time ratio vs no periodic yields 1 10 100 1,000 5,000 10,000 Handlers per turn (tested settings) 1 0 0 1 0 1 Whole-run ratio (log scale) ASYNCIFY: elapsed-time ratio vs no periodic yields Chain controls and whole-program comparisons All six turn limits | Same callback and timestamp counts within each control pair Ratios below 1 are observed whole-program outcomes, not negative yield costs. Runtime effects confound subtraction. Primary: 7 runs; other groups: 3. Error bars show the range of paired ratios. LCG updates are source-level work, not a guarantee of 64 instructions after optimization.
Figure 3. Callback chain controls
2026-11-07T01:31:43.113219 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ 1 10 100 1,000 5,000 10,000 Handlers per turn (tested settings) 1 0 1 1 0 2 1 0 3 1 0 4 Microseconds (log scale) Chain tails: p99 and largest observed gap JSPI maximum JSPI p99 ASYNCIFY maximum ASYNCIFY p99 1 0 1 1 0 2 Nanoseconds per iteration (log scale) JS to Wasm increment loop JS monotonic clock study Wasm clock via JS study JS wall-clock study Adjacent Wasm timestamps Wasm to JS + timestamps Synchronous and clock-read controls JSPI ASYNCIFY Isolated monotonic Ordinary monotonic Wall clock 1 0 1 1 0 2 1 0 3 Microseconds (log scale) 5 us 100 us 1,000 us Observed positive clock steps Isolated page Ordinary page 0 20 40 60 80 100 Percent of samples 30.9% 95.9% 22.6% 95.3% Direct samples recorded as zero JSPI ASYNCIFY Tails, clocks and measurement resolution Extreme observations are retained | A quantized zero is not proof of a zero-cost operation Clock studies include loop overhead; the trivial synchronous export may be inlined. Wall-clock step: where observed. Wasm and JS monotonic clocks share performance.now(). Maximums are observations, not guaranteed latency bounds.
Figure 4. Tails and observed clocks

Measured cost of yielding to the browser

On 2026-10-15, a direct round trip through the library’s actual webcpp_asio_yield() took about 4.06 microseconds with JSPI and 4.74 microseconds with Asyncify. These are medians of seven per-run means, not the duration of a batch of callbacks and not a real-time guarantee. One microsecond is 0.001 milliseconds.

The benchmark ran locally on an Apple M5 Max, 128 GiB RAM, macOS 27.0 (26A428), HeadlessChrome 153.0.8010.12, Emscripten 6.0.11 and Boost 1.92. Both compilation and linking used Release -O3; NDEBUG was enabled. The primary matrix enabled exceptions and cross-origin isolation. Additional cases disabled exceptions or isolation and exercised an arithmetic workload. No CI ran. The benchmark used explicit limits; the configured default was 1,000 at measurement time. The subsequent policy decision below changes it to 100.

From the original 1,000 default to 100

The value 1,000 predates the isolated yield-cost benchmark. It was specified as the initial scheduling policy in design decision D3 and the implementation plan. The design recorded a timer witness: with that limit, setTimeout(0) ran after about 1,000 handlers instead of waiting for the entire ready chain. That establishes that yielding happens; it does not derive an optimal limit. No calculation selecting 1,000 over all other limits was recorded there.

Task 13 subsequently checked whether keeping that value was acceptable for its trivial-handler workload. Its local Chrome experiment measured full 1,000-handler turns in three debug runs on 2026-10-14. The p95 was 0.7 ms for JSPI and 1.6 ms for Asyncify in every run. Animation callbacks occurred about 60 times per second; the unbounded controls had none during the observed work. The measured maxima were 1.8-1.9 ms and 8.9-9.2 ms, respectively. These are historical batch durations, distinct from the Release yield latencies below. The complete historical table remains in the library’s AGENTS.md.

The predeclared stop criterion was a turn p95 above 8 ms in either variant. Its motivation was to leave roughly half of a 60 Hz frame’s 16.7 ms interval for browser work. This is a screening heuristic, not a guarantee of frame rate: p95 does not bound every turn, browser work varies, and an animation callback does not prove that particular pixels were painted. The observations passed that criterion, so the existing default was retained.

The 2026-10-15 Release benchmark then measured the missing part: the actual cost of yielding. It supports amortizing that cost across cheap callbacks; it does not retrospectively turn 1,000 into a mathematically derived optimum. The documented rationale is therefore: an initial configurable policy, retained after a workload-specific responsiveness check, with its scheduling cost now measured independently. Choosing an optimal default would require an explicit responsiveness/overhead objective and representative workloads across the supported browsers and hardware.

On 2026-10-15, after reviewing these results, the owner selected 100 as the new default to favor browser responsiveness. In a continuously ready chain, it offers roughly ten times as many yields as 1,000. The measured boundary gaps imply about 44.0/54.5 ms of accumulated scheduling time per million handlers at 100 (JSPI/Asyncify), versus 4.64/5.73 ms at 1,000. The additional 39/49 ms is an extrapolation from this machine, not one uninterrupted pause.

For illustration, 100 callbacks that each take 50 us occupy about 5 ms, whereas 1,000 occupy about 50 ms, excluding scheduling overhead. These are calculated examples, not measured application response times. Browser work gets an opportunity at a yield, not a guarantee that an input or frame runs before Wasm resumes. A long handler is never preempted; both ready handlers and completions after a wait consume the configured budget, as described in The run family. The choice of 100 is a responsiveness-oriented policy, not proof of an optimum. Applications can still select 1,000 or another value.

What was timed

The direct measurement surrounds the production function without changing its implementation. The C++ steady-clock timestamp is read immediately before the call and immediately after it resumes. Their difference in milliseconds is multiplied by 1,000 to report microseconds. The compiled implementation is in bench/yield/yield_program.cpp.

That function awaits a Promise, creates a MessageChannel, posts a message, closes port1 in its message handler and resolves the Promise. The suspended Wasm execution then resumes. This is a cooperative browser event-loop yield, not a measurement of an operating-system thread context switch.

The chain measurement uses boost::asio::post to schedule its next handler. It records the end of the last callback before a yield, after posting its successor, and the entry of the first callback after the yield. This excludes batch execution, but includes the small dispatcher return/reentry around the yield. A matched control records the same boundaries with periodic yielding disabled. It uses exactly the same number of handlers and clock reads.

Direct round-trip latency

Each primary row contains seven fresh-page runs of 10,000 yields each. Percentiles are nearest-rank quantiles per run, then medians across runs. The maximum is the largest individual observation across all repetitions. The mean range exposes variation between independent runs.

Path Mean, us Run means, us p50, us p95, us p99, us Maximum, us

jspi

4.06

3.98-4.15

5

10

10

310

asyncify

4.74

4.59-4.94

5

10

10

805

js

3.93

3.85-4.01

5

10

10

285

The JavaScript control implements the same Promise/MessageChannel sequence without entering Wasm. Its similar cost suggests that browser scheduling and channel/Promise management account for much of the round trip in this setup. Subtracting its mean from the Wasm mean does not isolate an ABI transition: these are separate runs, with different optimized code and runtime work.

Actual yield gaps with different turn limits

Each cell below is a yield gap, not time spent running the callbacks. Each limit has seven repetitions per variant. Runs contain at least 100,000 handlers and at least 1,024 yield samples. Limit 1 uses 100,000 samples; limit 10 uses 10,000; the other limits use 1,024.

Handlers per turn JSPI gap, us Asyncify gap, us JSPI p95, us Asyncify p95, us JSPI amortized, ns/handler Asyncify amortized, ns/handler

1

4.18

4.85

10

10

4183.95

4850.00

10

4.15

4.98

10

10

414.95

498.05

100

4.40

5.45

10

10

44.04

54.54

1000

4.64

5.73

10

10

4.64

5.73

5000

4.82

6.40

10

10

0.96

1.28

10000

4.86

6.93

10

10

0.49

0.69

The amortized columns divide the measured gap by the turn limit. They are an estimate of scheduling cost per handler, not the handler’s execution time. For example, one million handlers with a limit of 1 imply roughly four to five seconds of accumulated yield gaps at these means. A limit of 100 implies roughly 44-55 milliseconds; a limit of 1,000 roughly 5-6 milliseconds. These extrapolations describe this workload and machine, not all applications.

The largest chain gaps were 5.01 ms with JSPI and 39.72 ms with Asyncify, both at limit 1. No samples were removed. The benchmark does not identify whether these outliers came from collection, scheduling or another cause. A browser yield gives an opportunity to service the page; it does not guarantee that rendering or a particular queued task executes before resumption.

Where the instrumented interval was spent

A separate run observes six JavaScript timestamps inside the MessageChannel path. The observer is warmed before collection. These observations perturb the operation: the median mean rises from 4.06 to 4.85 us for JSPI and from 4.74 to 5.57 us for Asyncify. Consequently the following decomposition is of the instrumented path, not a claim that the observer is free.

All entries below are arithmetic means across seven runs of 10,000 samples; they add to the arithmetic mean of the traced round trip. Sub-resolution values are aggregate estimates, not individually resolved durations.

Observed segment JSPI mean, us Asyncify mean, us

C++ start to channel observer entry

0.21

0.26

Native MessageChannel construction

1.06

1.12

Handler/observer setup before post

0.67

0.70

Synchronous postMessage call

0.47

0.50

Post return to message-handler entry

1.20

1.52

Message handler: close port and resolve

1.01

1.02

Handler return to C++ resumption

0.21

0.47

Instrumented total

4.83

5.59

Post-return-to-delivery includes suspension/unwinding and browser scheduling; it is not a pure queue-residence measurement. The last segment includes Promise/microtask continuation, runtime resumption and the C++ timestamp. The entry segment includes Promise setup before the first observed channel operation. Handler setup includes observer allocations and timestamp reads. These measurements cannot isolate pure engine suspension and restoration instructions from all surrounding work.

A validation-only 2 ms busy wait inserted into the JavaScript message handler was detected in that segment, about 2.001 ms on both variants. It was absent from all 442 production-mechanism measurement cases.

Clock resolution and synchronous controls

In this Emscripten build, C++ steady_clock reaches clock_gettime, WASI’s monotonic clock and then emscripten_get_now, which uses performance.now(). C++ system_clock reaches the same wall-clock source as Date.now(). These are not independent hardware clocks. Two thousand bracketed reads before and after each Wasm case verified their correspondence.

Observed positive clock steps were about 5 us in an isolated page and 100 us in an ordinary page. Date.now() advanced in 1 ms steps where a positive step was observed. Isolated-page direct yield samples therefore include many zeros despite a nonzero aggregate mean. In an ordinary page, about 96% of JSPI and 95% of Asyncify direct samples were zero; the median p95 was also zero. Those individual percentiles cannot resolve a 4-5 us operation. The ordinary-page mean still agreed: 4.03 us JSPI and 4.73 us Asyncify.

Control JSPI, ns/iteration Asyncify, ns/iteration

Adjacent C++ timestamps

109.1

114.0

C++ → JS counter call, including timestamps

111.1

135.4

Optimized JS → C++ increment loop

2.3

4.1

JS performance clock study loop

69.6

71.5

JS → C++ monotonic clock study loop

118.6

141.7

JS wall-clock study loop

28.0

28.2

Clock-study values include loop and comparison overhead. The JS-to-C++ control uses one million synchronous calls, with observable results; an optimizing engine may inline this trivial export. The C++-to-JS control increments an observable counter between the same two C++ timestamps as the clock-only control. Neither performs an asynchronous yield. Small differences between these controls are not a precise standalone ABI-cost estimate. No per-sample clock-floor subtraction was performed on the reported yield latencies.

Exceptions and arithmetic controls

Variant Exceptions on, us Exceptions off, us

jspi

4.06

4.03

asyncify

4.74

4.43

Exception-free controls used three repetitions, including all six turn limits. The additional arithmetic control used 64 source-level LCG updates per handler, with an independently verified checksum. This is not a claim of 64 machine instructions: optimization can combine arithmetic. All its raw run statistics, plus the traced chain runs, are retained with the benchmark results.

What the measurements justify

For the instrumented trivial chain, limit 1 took 17.29 times the matched no-periodic-yield control with JSPI and 14.49 times with Asyncify. At limit 100 the ratios were 2.09 and 1.43; at limit 1,000 they were 1.15 and 1.05. These are measured whole-program ratios, including the clocks in both cases, not universal application overhead factors.

Subtracting whole-run durations is unreliable for small differences. Some large-limit pairs produced negative differences. Exception-free Asyncify’s large-limit controls were consistently slower than the yielding runs. This experiment does not identify the cause; execution/tiering, allocation and other runtime effects can confound such controls. The retained CSV and JSON include these results. They must not be described as negative yield latency. The direct interval and callback-boundary observations remain the primary latency measurements.

The evidence supports amortizing yields when handlers are very cheap. It does not prove that 1,000 is optimal, or that 1 is always inappropriate. A heavy handler can make a 4-5 us yield negligible. Choosing a limit balances accumulated scheduling cost against time spent away from the browser. Counting handlers cannot bound that time when their costs vary, and no limit interrupts a handler in the middle. Configure the limit as described in How to configure the turn limit; the current default is 100.

Relating the limit to an application’s cost budget

For a continuously ready chain with roughly uniform callbacks, let Y be mean yield latency, C the mean cost of handling one callback without a forced yield, and N the number of callbacks per turn. The scheduling cost per callback is approximately Y / N. Relative to the callback work, the added cost is approximately Y / (N * C). These are workload estimates, not latency bounds; they omit variability and other browser work.

For an allowed additional cost ratio r, the estimate asks for N >= Y / (r * C), rounded up to a positive integer. This must be balanced against time away from the browser, approximately N * C for this continuous chain. The general run-family paths described in A turn at a time can have more than one turn’s handlers between yields, and no handler is preempted.

For illustration only, assume Y = 5 us and allow 10% added scheduling cost:

Assumed callback cost C Estimated minimum N Callback work per full turn

0.05 us

1,000

50 us

1 us

50

50 us

100 us

1

100 us

These assumed callback costs and the 10% objective did not produce the original default. They show why a count cannot be selected from yield latency alone. A limit of 1 can be inexpensive for substantial callbacks; 1,000 can amortize scheduling for extremely cheap callbacks. Conversely, 1,000 callbacks that each take 100 us can occupy the thread for about 100 ms before a periodic yield in this chain. Measure the actual application and choose its limit using the build definition or the per-context option.

Charts and complete tables

These charts use the recorded observations. Marked error bars show ranges between independent runs, not confidence intervals. Logarithmic axes are labeled. The per-callback scheduling cost is derived by dividing a yield gap by the limit. The complete aggregate table is bench/yield/results/2026-10-15/figures/all-configurations.csv (102 configurations); runs.csv in its parent directory retains all 442 runs. All summary fields, including ranges, percentiles, clocks and phase components, are preserved in the aggregate CSV. The figures directory also contains a four-page PDF and separate PNG/SVG images.

2026-10-15T03:06:30.693620 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ 1 10 100 1,000 5,000 10,000 Handlers per turn (tested settings) 0 1 2 3 4 5 6 7 8 Microseconds per yield gap 4.18 4.15 4.40 4.64 4.82 4.86 4.85 4.98 5.45 5.73 6.40 6.93 Measured boundary gap: excludes callback batch work JSPI ASYNCIFY 1 10 100 1,000 5,000 10,000 Handlers per turn (tested settings) 1 0 0 1 0 1 1 0 2 1 0 3 Nanoseconds per callback (log scale) Derived scheduling cost per callback JSPI ASYNCIFY Yield latency and turn limits Release -O3 | Exceptions enabled | Isolated page | Seven repetitions per setting Dots: median of per-run means. Error bars: range of run means, not confidence intervals. Amortization = measured gap / turn limit. Gaps include small dispatcher return/reentry costs.
Figure 5. Yield latency and amortization
2026-10-15T03:06:31.033565 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ 0 1 2 3 4 5 6 Microseconds per round trip JSPI / EH on JSPI / EH on / traced ASYNCIFY / EH on ASYNCIFY / EH on / traced JSPI / EH off JSPI / EH off / traced ASYNCIFY / EH off ASYNCIFY / EH off / traced JSPI / ordinary page JSPI / ordinary page / traced ASYNCIFY / ordinary page ASYNCIFY / ordinary page / traced JavaScript only JavaScript only / traced 4.06 4.85 4.74 5.57 4.03 4.92 4.43 5.31 4.03 4.83 4.73 5.56 3.93 4.83 Direct latency: median of run means 0 1 2 3 4 5 6 Microseconds, arithmetic means of traced runs JSPI / EH on ASYNCIFY / EH on JSPI / EH off ASYNCIFY / EH off JSPI / ordinary page ASYNCIFY / ordinary page JavaScript only 4.83 5.59 4.89 5.31 4.84 5.56 4.82 Instrumented phases: means add to the total Caller entry Channel construction Handler + observer setup postMessage Post return to delivery Close port + resolve Resume Direct round trips and observed phases Same Promise / MessageChannel mechanism | Untraced and traced measurements kept separate Primary and JS-only controls: 7 runs; EH-off and ordinary-page controls: 3 runs. The observer adds cost. Post-to-delivery includes suspension and scheduling, not pure queue wait. Sub-resolution phase values are aggregate estimates; individual clock steps are 5 or 100 us.
Figure 6. Direct controls and instrumented phases
2026-10-15T03:06:31.421396 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ 1 10 100 1,000 5,000 10,000 Handlers per turn (tested settings) 0 2 4 6 8 10 Microseconds (median of run means) JSPI: measured yield boundary gaps EH on, untraced EH off, untraced 64 source-level LCG updates EH on, traced 1 10 100 1,000 5,000 10,000 Handlers per turn (tested settings) 0 2 4 6 8 10 Microseconds (median of run means) ASYNCIFY: measured yield boundary gaps EH on, untraced EH off, untraced 64 source-level LCG updates EH on, traced 1 10 100 1,000 5,000 10,000 Handlers per turn (tested settings) 1 0 0 1 0 1 Whole-run ratio (log scale) JSPI: elapsed-time ratio vs no periodic yields 1 10 100 1,000 5,000 10,000 Handlers per turn (tested settings) 1 0 0 1 0 1 Whole-run ratio (log scale) ASYNCIFY: elapsed-time ratio vs no periodic yields Chain controls and whole-program comparisons All six turn limits | Same callback and timestamp counts within each control pair Ratios below 1 are observed whole-program outcomes, not negative yield costs. Runtime effects confound subtraction. Primary: 7 runs; other groups: 3. Error bars show the range of paired ratios. LCG updates are source-level work, not a guarantee of 64 instructions after optimization.
Figure 7. Chain controls and whole-program comparisons
2026-10-15T03:06:31.817794 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ 1 10 100 1,000 5,000 10,000 Handlers per turn (tested settings) 1 0 1 1 0 2 1 0 3 1 0 4 Microseconds (log scale) Chain tails: p99 and largest observed gap JSPI maximum JSPI p99 ASYNCIFY maximum ASYNCIFY p99 1 0 1 1 0 2 Nanoseconds per iteration (log scale) JS to Wasm increment loop JS monotonic clock study Wasm clock via JS study JS wall-clock study Adjacent Wasm timestamps Wasm to JS + timestamps Synchronous and clock-read controls JSPI ASYNCIFY Isolated monotonic Ordinary monotonic Wall clock 1 0 0 1 0 1 1 0 2 1 0 3 Microseconds (log scale) 5 us 100 us 1,000 us Observed positive clock steps Isolated page Ordinary page 0 20 40 60 80 100 Percent of samples 31.4% 96.0% 23.1% 95.3% Direct samples recorded as zero JSPI ASYNCIFY Tails, clocks and measurement resolution Extreme observations are retained | A quantized zero is not proof of a zero-cost operation Clock studies include loop overhead; the trivial synchronous export may be inlined. Wall-clock step: where observed. Wasm and JS monotonic clocks share performance.now(). Maximums are observations, not guaranteed latency bounds.
Figure 8. Tails and clock resolution

Reproduce and inspect

The manual benchmark is in bench/yield/; its README documents exact build, run and analysis commands. It is not connected to a CI lane. The recorded results/2026-10-15/runs.csv retains statistics for every case, summary.json groups repetitions, and build.json identifies the hardware, toolchain and source/binary hashes. Full timestamp arrays are also preserved in the local raw-data archive identified in the README.

The run used 442 sequential fresh-page cases in deterministic shuffled order (seed 20261015), totaling 970,139,132 operations and 9,429,856 timing pairs. Primary cases had seven repetitions; secondary controls had three. Direct and chain Wasm cases first warmed 512 actual yields, and chain cases additionally warmed 10,001 posted handlers. Builds completed before measurement started. There was no polling timer in the measured page. The machine was not isolated from all other OS activity, and this headless, otherwise idle-page experiment does not represent a loaded application’s rendering or input workload.

Browser events

On emscripten every event source of asio and of the libraries built on it, a WebSocket’s onmessage, a fetch promise, a WebRTC callback, is a JavaScript function made by the io_context’s bridge, webcpp::asio::browser::bridge. The bridge is a service of the io_context, Boost.Asio’s own mechanism, so that it is made with the context’s allocator, on first use, and shut down and destroyed with the context. From the test bridge, where two events delivered before run wait for it:

webcpp::asio::io_context io;
counter listener(io, 0);  // a registration, which posts each event it receives
auto& bridge = webcpp::asio::use_service<webcpp::asio::browser::bridge>(io);
const std::uint64_t key = bridge.add(listener);
const emscripten::val deliver = bridge.function(key);  // for JavaScript to call
deliver(1);
deliver(2);
BOOST_TEST_EQ(listener.received, 0);  // posted, and waiting for run
BOOST_TEST_EQ(io.run(), 2U);          // lint-run: the test's event loop
BOOST_TEST_EQ(listener.received, 2);
bridge.remove(key);

A registration is what an event delivered through the bridge reaches: an object of a class derived from webcpp::asio::browser::registration, owned and allocated by whoever adds it, an operation, a stream or a channel. Its deliver is given the event and returns whether the registration is done, in which case the bridge removes it; its shutdown is the context’s shutdown, which destroys what is pending without calling it. The bridge keeps a pointer to each, by key, in a map allocated with the context’s allocator. Natively there is no bridge: browser/ builds on emscripten alone.

A browser event delivered through the bridge only posts; a listener is no outstanding work. A registration’s deliver posts what the event completes or notifies to the io_context, and does nothing else: it never polls, runs or dispatches. The post wakes a suspended run through the reactor, and an event that arrives while no run is active is posted and waits for the next one. A registered listener keeps no run alive: run returns when nothing is pending, as natively a socket with no pending operation does not keep it.

Posting is the only choice. While run is suspended in the reactor’s select, the frame that Boost’s scheduler pushed for it stays on the call stack, so that an event sees running_in_this_thread() true, and webcpp::asio::dispatch called there runs its handler at once, inside the event and on its stack, rather than on the stack of run (measured with Emscripten 6.0.11). And calling the run family from an event fails at its first suspension: under JSPI it throws a SuspendError, and under Asyncify it starts an unwind that corrupts the suspended main (see Who may call it). Under Asyncify a wake must also come from JavaScript with no compiled code on the stack, which a post gives. So an event may call what returns at once without suspending, which posting is, and no member of the run family, nor poll, poll_one or dispatch. While it delivers, the bridge says so, delivering(), so that the run family can refuse a call made from inside a delivery. Only the bridge’s own JavaScript functions deliver, and they count the deliveries in progress, nested ones included, which delivering() reads. Through the bridge, a program can neither deliver outside that count, deliver being private, nor change it, delivering() taking no value; the export those functions call is the JavaScript boundary’s, declared in a detail header, and calling it from C++ is outside the contract.

A registration’s key is never reused; an event of a removed key, or of a destroyed io_context, finds nothing. Keys are std::uint64_t values counted from 1, which JavaScript holds as a BigInt, so that no count of registrations a program reaches wraps around. Each function the bridge makes carries its key and a token that the bridge clears at its shutdown: an event of a key the bridge no longer holds delivers nothing, and an event that arrives after the io_context was destroyed does not reach WebAssembly at all. A registration must outlive its key, and is removed before it is destroyed; the context’s shutdown calls the shutdown of each registration still held.

An exception that escapes a delivery, a C++ exception from a registration’s deliver or a JavaScript error from a function it calls, is caught at the bridge’s boundary and reported with the page’s reportError, or console.error where there is none, and the event that raised it is lost. A C++ exception is caught in C++, which frees its object: one that reached the page would keep it for good. A JavaScript error passes every C++ catch and leaves WebAssembly without running its frames’ epilogues, in every build; it runs their destructors in a build with WebAssembly exceptions, the JSPI variant’s, and skips them with JavaScript exceptions, the Asyncify variant’s, and without exceptions (measured with Emscripten 6.0.11). So the JavaScript side of the boundary keeps what must hold however a delivery ends: it puts WebAssembly’s stack pointer back where it was before the call, puts the count of deliveries in progress back, and frees the event’s handle, which C++ only borrows. Where destructors are skipped, what the registration’s own frames owned is not freed: a registration that calls JavaScript which may throw catches the error there.

What the boundary does not catch is the runtime’s own. A trap, a WebAssembly.RuntimeError, which Emscripten’s abort() throws too, goes on to the page after the stack pointer is put back, as it does from any other call into WebAssembly, rather than being reported and swallowed as an error of the program’s; and the ExitStatus that exit() throws, or Emscripten’s 'unwind', ends the delivery without a report, as Emscripten’s own callbacks do. A handler’s exception is another matter: it is thrown by a handler that run runs, on the stack of main, and propagates out of run, as Boost’s does.

A JavaScript error that a handler lets escape crosses no boundary of asio’s: it leaves run, and the page’s JavaScript may catch it around a call of an export listed for suspension and call that export again. With WebAssembly exceptions the frames it leaves run their destructors, Boost’s and asio’s, and the next run runs as after a C++ exception. With JavaScript exceptions, and without exceptions, the destructors are skipped and the context is left broken whatever asio does. Boost’s scheduler keeps the finished handler’s work counted, so that the base run, reached through a reference to the shipped backend’s context, never returns once out of work. Boost’s call stack keeps the frame run pushed, so that running_in_this_thread() is true outside any run, and a dispatch anywhere runs its handler at once. And the run family’s flag stays set, so that every later call asserts and returns 0. No boundary can put Boost’s state back, since the frames that would are the ones the error skips, so asio does not put its flag back either: a refusal reports the broken context where a run that never returns would not. A handler that calls JavaScript which may throw catches the error in JavaScript, as a registration does. (Measured with Emscripten 6.0.11 in both variants, with exceptions and without: an export listed for suspension runs the context, a handler’s JavaScript error escapes it, the page catches the error and calls the export again.)

Held by bridge, in each variant, with exceptions and without them: an event posts and wakes run; events delivered before run wait for it; a listener and nothing pending let run return; a registration that is done is removed; an event of a removed key, and one of a destroyed io_context, find nothing, and the context’s destruction shuts its registrations down; 3,000 C++ exceptions, and 3,000 JavaScript errors, escaping deliveries called in a row from JavaScript are each reported, with the stack pointer where it was, as many Emval handles as before, and the bridge no longer delivering; a delivery dispatched from inside another, ending normally or with a JavaScript error, leaves the outer one delivering; and a trap goes on to the caller while 'unwind' and an ExitStatus pass unreported. By bridge_deliver_refused and bridge_set_delivering_refused, where a program that calls the bridge’s deliver, or gives delivering() a value, fails to compile, beside bridge_private, which compiles. And by em_js, which loads every JavaScript function of asio and of its tests, so that one that does not parse fails before main.

Promises and events

Tutorial: receive a value and a rejection

On Emscripten, browser::async_await connects a JavaScript Promise to an Asio executor. Build this example with b2 toolset=emscripten libs/asio/example//asio_promise.output.

#include <cstdio>
#include <webcpp/asio/browser/async_await.hpp>
#include <webcpp/asio/io_context.hpp>
#include <webcpp/test/exit_status.hpp>

int main() {
    webcpp::asio::io_context io;
    auto resolved = emscripten::val::global("Promise").call<emscripten::val>("resolve", 42);
    auto rejected = emscripten::val::global("Promise").call<emscripten::val>("reject", 9);
    int failures = 0;
    webcpp::asio::browser::async_await(
        io.get_executor(), resolved,
        [&](boost::system::error_code ec, const emscripten::val& value) {
            if (ec) {
                ++failures;
                return;
            }
            std::printf("resolved: %d\n", value.as<int>());
        });
    webcpp::asio::browser::async_await(
        io.get_executor(), rejected,
        [&](boost::system::error_code ec, const emscripten::val& reason) {
            if (ec != webcpp::asio::browser::error::promise_rejected) {
                ++failures;
                return;
            }
            std::printf("rejected: promise_rejected %d\n", reason.as<int>());
        });
    io.run();  // lint-run: main waits for both Promise completions
    return webcpp::test::exit_status(failures);
}

Expected output:

resolved: 42
rejected: promise_rejected 9

A callback receives an error code and an emscripten::val: success supplies the resolved value, and promise_rejected supplies the rejection reason. Embind is linked by the library’s build requirements.

How-to: choose a completion token or cancel a wait

Callbacks, webcpp::asio::deferred, webcpp::asio::use_awaitable and webcpp::cobalt::use_op use the same initiation. Coroutine tokens that turn errors into exceptions require exception support for that error path. Use an error-preserving completion token adapter for errors as values.

Bind a cancellation slot to the handler and emit terminal, partial or total to complete the wait with operation_aborted and undefined. none does nothing. Completion is posted, never invoked inside initiation or the cancellation signal. The Promise itself continues running; any late settlement finds no registration and cannot complete the operation again.

Reference: values, ownership and allocation

The completion signature is void(boost::system::error_code, emscripten::val). The rejection category is webcpp.asio, with value 1 and message the promise was rejected. JavaScript Promise.resolve normalizes inputs: an ordinary value is accepted, and already-settled Promises still complete asynchronously. An undefined rejection reason is preserved.

A pending operation owns outstanding work. A Promise that never settles keeps run waiting until cancellation. Destroying the context destroys its pending handler without invoking it; later settlements are ignored. Operation storage uses the handler’s associated allocator, while the bridge service and its map use the context’s allocator. The operation preserves the executor’s concrete type when passed directly, including its scheduling properties. An explicitly type-erased any_io_executor remains accepted, but Boost’s erased executor can allocate its dispatch wrappers independently of the handler allocator. Custom executors likewise control their own storage. For the measured allocation guarantee, pass io.get_executor() directly. See Allocation.

Explanation: why the bridge posts the result

JavaScript delivers the settlement through Browser events. The bridge posts completion so application code runs on the event-loop stack, where suspension is supported. It never calls the handler inline from a Promise reaction. See guarantees [asio-invariant-10] and [asio-invariant-11].

Await one browser event

browser::async_wait_event(executor, target, type, token) completes with the next event of the requested type. It uses a one-shot listener and posts the event to the executor. The event type is copied into a JavaScript string, including when initiation is deferred; the view needs no terminating null. A pending wait owns work. Terminal, partial or total cancellation removes the listener and posts operation_aborted with undefined; none does nothing. Context destruction removes the listener and destroys the handler silently. Storage follows the same allocator and executor rules as Promise waits.

Tutorial: receive a message

This example creates an EventTarget, waits for its next message, and schedules a JavaScript timer to send it. Build with b2 toolset=emscripten libs/asio/example//asio_event.output.

#include <emscripten/em_js.h>
#include <cstdio>
#include <webcpp/asio/browser/async_wait_event.hpp>
#include <webcpp/asio/io_context.hpp>
#include <webcpp/test/exit_status.hpp>

// clang-format off
EM_JS(void, send_event, (emscripten::EM_VAL handle), {
    const target = Emval.toValue(handle);
    setTimeout(() => target.dispatchEvent(
        new CustomEvent('message', {detail: 5})), 20);
});
// clang-format on

int main() {
    webcpp::asio::io_context io;
    const auto target = emscripten::val::global("EventTarget").new_();
    int failures = 0;
    webcpp::asio::browser::async_wait_event(
        io.get_executor(), target, "message",
        [&](boost::system::error_code ec, const emscripten::val& event) {
            if (ec) {
                ++failures;
                return;
            }
            std::printf("event: message %d\n", event["detail"].as<int>());
        });
    send_event(target.as_handle());
    io.run();  // lint-run: main waits for the browser event
    return webcpp::test::exit_status(failures);
}

Expected output:

event: message 5

The operation removes its listener before posting completion. To receive another event, initiate another wait. Cancelling the wait does not cancel a JavaScript timer that might later dispatch an event.

Pending promise and event waits keep both the owning executor and the handler’s associated executor active. Binding a completion to another context does not require restarting that context after settlement. Cancellation transfers the completion to it; destroying the owning context releases both work guards.

Timers

steady_timer, system_timer and basic_waitable_timer are aliases of Boost.Asio’s timers on native, Emscripten and WASIp2/P3. Their executors, completion tokens, associated allocators and per-operation cancellation slots keep Boost’s interfaces and behaviour.

Use steady_timer for an interval measured by a monotonic clock, and system_timer for a deadline on the system clock. Adjusting the system clock can affect a system timer; it does not change a steady timer’s clock. A deadline makes a handler eligible to run, not a promise that the host will execute it at that exact instant.

Waiting and cancellation

On Emscripten the timers sit in Boost.Asio’s reactor queue. The run family waits through the selected suspension variant, JSPI or Asyncify (Building), allowing JavaScript to run while it waits. The reactor caps each wait at five minutes; an idle wait therefore holds one JavaScript setTimeout of at most 300 seconds. This bounds one reactor wait, not the duration a program may give a timer.

Cancelling a timer completes its pending waits with webcpp::asio::error::operation_aborted. An operation already ready for completion cannot be cancelled retroactively. To cancel a particular wait, bind a cancellation slot to its completion handler. A terminal signal on that slot cancels that wait without cancelling another wait on the same timer. This test cancels the other wait explicitly only after checking that it remains pending:

void a_cancellation_slot_aborts_only_its_wait() {
    std::cout << "case: a cancellation slot aborts only its wait\n";
    webcpp::asio::io_context io;
    webcpp::asio::cancellation_signal signal;
    const auto start = std::chrono::steady_clock::now();
    webcpp::asio::steady_timer timer(io, start + 10s);
    webcpp::asio::steady_timer trigger(io, start + 10ms);
    std::size_t cancelled = 0;
    std::size_t other = 0;
    std::size_t emitted = 0;
    timer.async_wait(
        webcpp::asio::bind_cancellation_slot(signal.slot(), [&](boost::system::error_code ec) {
            ++cancelled;
            BOOST_TEST(ec == webcpp::asio::error::operation_aborted);
            BOOST_TEST_EQ(emitted, 1U);
            BOOST_TEST_EQ(other, 0U);
            // The unbound wait is still pending. Cancel it explicitly to finish the case.
            BOOST_TEST_EQ(timer.cancel(), 1U);
            std::cout << "slot cancellation: " << ec.message() << "\n";
        }));
    timer.async_wait([&](boost::system::error_code ec) {
        ++other;
        BOOST_TEST(ec == webcpp::asio::error::operation_aborted);
        BOOST_TEST_EQ(cancelled, 1U);
    });
    trigger.async_wait([&](boost::system::error_code ec) {
        BOOST_TEST(!ec);
        ++emitted;
        signal.emit(webcpp::asio::cancellation_type::terminal);
    });
    io.run();  // lint-run: the test's event loop
    BOOST_TEST_EQ(emitted, 1U);
    BOOST_TEST_EQ(cancelled, 1U);
    BOOST_TEST_EQ(other, 1U);
}

Beast’s timeouts

Boost.Beast’s basic_stream and WebSocket stream use Boost.Asio timers internally. Their timeout handling therefore uses the same reactor queue and works with both suspension variants. The test below starts a WebSocket handshake over Beast’s in-memory test stream. Its peer sends no handshake, so the completion reports boost::beast::error::timeout:

void beast_s_handshake_timeout_fires() {
    std::cout << "case: Beast's handshake timeout fires\n";
    webcpp::asio::io_context io;
    webcpp::beast_backend::test::stream peer(io);
    webcpp::beast_backend::websocket::stream<webcpp::beast_backend::test::stream> ws(io);
    webcpp::beast_backend::websocket::stream_base::timeout timeout{};
    timeout.handshake_timeout = 100ms;
    timeout.idle_timeout = webcpp::beast_backend::websocket::stream_base::none();
    timeout.keep_alive_pings = false;
    ws.set_option(timeout);
    ws.next_layer().connect(peer);
    std::size_t completions = 0;
    ws.async_accept([&completions](boost::system::error_code ec) {
        ++completions;
        BOOST_TEST(ec == webcpp::beast_backend::error::timeout);
        std::cout << "handshake: " << ec.message() << "\n";
    });
    io.run();  // lint-run: the test's event loop
    BOOST_TEST_EQ(completions, 1U);
}

This checks Beast’s timeout integration. It does not open a network connection or provide a browser WebSocket transport.

What the timer tests establish

Guarantee 8 records the timer contract.

The timers_native test runs natively. The timers browser tests run WebAssembly under Node with JSPI and Asyncify, each with and without exceptions. They check steady timers registered with deadlines of 60, 20 and 40 milliseconds against completion order 20, 40, 60; a system timer; whole-timer and per-operation cancellation; and Beast’s handshake timeout. The three steady deadlines share one starting instant. The tests check completion order and error values, without requiring exact elapsed times.

How to schedule deadlines and cancel a wait

Use a common clock origin when several waits belong to the same schedule. This program registers 60, 20 and 40 ms deadlines, then runs their handlers. After that run finishes, it restarts the context and cancels a separate pending wait:

#include <webcpp/asio/io_context.hpp>
#include <webcpp/asio/steady_timer.hpp>

#include <webcpp/test/exit_status.hpp>

#include <webcpp/asio/error.hpp>

#include <chrono>
#include <cstdio>

namespace asio = webcpp::asio;
using namespace std::chrono_literals;

int main() {
    asio::io_context io;
    const auto start = std::chrono::steady_clock::now();
    asio::steady_timer sixty(io, start + 60ms);
    asio::steady_timer twenty(io, start + 20ms);
    asio::steady_timer forty(io, start + 40ms);
    const auto report = [](const char* label) {
        return [label](boost::system::error_code ec) {
            if (ec) {
                std::printf("timer error: %d\n", ec.value());
            } else {
                std::puts(label);
            }
        };
    };
    sixty.async_wait(report("60 ms"));
    twenty.async_wait(report("20 ms"));
    forty.async_wait(report("40 ms"));
    io.run();  // lint-run: main waits for the three deadlines

    io.restart();
    asio::steady_timer cancelled(io, std::chrono::steady_clock::time_point::max());
    cancelled.async_wait([](boost::system::error_code ec) {
        if (ec == webcpp::asio::error::operation_aborted) {
            std::puts("cancelled: operation_aborted");
        } else {
            std::printf("unexpected cancellation result: %d\n", ec.value());
        }
    });
    cancelled.cancel();
    io.run();  // lint-run: main delivers the cancelled wait's completion
    return webcpp::test::exit_status(0);
}
b2 toolset=emscripten libs/asio/example//asio_timers.output
20 ms
40 ms
60 ms
cancelled: operation_aborted

The labels identify the requested deadlines, not measured completion times. restart allows another run after the first exhausted its work. The final timer uses the clock’s maximum deadline so it remains pending until cancel. Cancelling schedules the aborted completion; the second run delivers it. Keeping these two phases separate makes the displayed order independent of when the host schedules cancellation against ready timers. For cancellation of one wait while another remains pending, use the slot example in Waiting and cancellation.

Use Cobalt with Asio

Cobalt now owns its coroutine facade, compiled core, runner and optional SSL wrapper in a separate library. Include webcpp/cobalt/ headers and use webcpp::cobalt with webcpp::asio. Native core and plain I/O names are Boost identities; Wasm selects compatible shipped implementations. Consumers do not patch Boost or depend on replacement-header search order.

Tutorial: wait for a timer in co_main

The compiled example moved to libs/cobalt/example/asio_cobalt.cpp. The Cobalt timer tutorial shows the complete source, prerequisites, command and checked output. The application still writes co_main; the runner owns main.

How to link the integration

Select /webcpp/cobalt//cobalt for an application defining co_main, or /webcpp/cobalt//core when the application supplies main and drives its own context. The old /webcpp/asio//cobalt name is a compatibility alias. Do not also link a system Cobalt archive or another runner.

The external build recipe lists the shipped sources and dependencies for another build system. Apply executor, PMR, exception and thread configuration consistently to every source. The exception-mode contract retains the informational warning for Cobalt issue 287. Result-based error handling does not repair that pending-coroutine move path.

Use the corrected SSL stream

Include webcpp/cobalt/io/ssl.hpp. Select /webcpp/cobalt//cobalt_ssl with the runner or /webcpp/cobalt//io_ssl with a custom main. The old /webcpp/asio//cobalt_ssl name is a compatibility alias. These optional targets share Asio’s source-built OpenSSL and CA provider; plain Cobalt does not link TLS. Browser HTTPS/WSS instead uses host TLS and its certificate policy.

Prepare the context with webcpp::asio::make_tls_client_context, check its result and configure hostname verification and SNI as described in How-to: configure trusted certificate authorities. Cobalt’s SSL context is the selected Asio context type. The corrected native SSL stream is an explicit exception to native Boost type identity; it is not a modification to an installed Boost header.

Handshake and stream state

The Cobalt SSL state contract describes STARTTLS, buffered handshakes, cancellation and shutdown. After a failed or cancelled handshake the corrected wrapper blocks application I/O instead of falling back to plaintext. Keep the concrete SSL stream type for the corrected native composed read/write overloads; type erasure can select upstream behavior.

Run the local wrapper checks

From the configured superproject root:

b2 -a variant=release libs/cobalt/test/tls//tls
b2 -a toolset=clang-wasip3 variant=release libs/cobalt/test/tls//tls

The TLS and cancellation tests use real local peers and temporary certificates with TLS 1.2 and 1.3. WASI tests need network grants but no filesystem CA preopen. Keep native upstream cancellation limitations distinct from the corrected SSL path.

Why the Wasm runner changes

Native core and runner sources remain byte-identical to Boost. The browser runner drives WebCPP’s bounded context, offering a scheduling opportunity after a full turn of at most the configured handler count, currently 100 by default. It cannot interrupt a long handler. Configure that value as in Configure the build’s default turn limit, consistently for the runner and application.

The WASI runner omits unsupported POSIX signal registration. Internal Asio and Cobalt cancellation remain available, but automatic SIGINT/SIGTERM shutdown does not. A host must use an explicit application shutdown protocol; stopping a context or terminating a component does not guarantee pending-operation cleanup.

Completion and limitations

The browser runner preserves the coroutine’s exit status, including after an Asyncify suspension. WASI SDK 34 command startup maps nonzero results to host status 1; tests distinguish that failure result from a trap. See Cobalt’s test contract for the current validation gates and native upstream limitations.

Checks and historical suspension storage

The runner tests now belong to Cobalt:

b2 libs/cobalt/test//cobalt
b2 toolset=emscripten libs/cobalt/test//cobalt
b2 toolset=emscripten libs/cobalt/test//cobalt_asyncify

The historical 2026-10-14 Asyncify probe measured a maximum of 1,088 bytes in Release with the default link, 384 with an optimized link, and 1,032 in Debug. These describe the earlier source revision. They are suspension storage, not binary size or a bound on arbitrary application call depth. Current migration measurements must be recorded separately; the configured stack remains 8,192 bytes.

Historical reference: release binary sizes

The timer example from the earlier integrated distribution was measured with Emscripten 6.0.11, Boost 1.92, C++20 and Node 26.7.0 on macOS arm64, on 2026-10-15. Each of the twelve configurations used its own build directory, with variant=release, NDEBUG, matching compile and link optimization flags, and an 8192-byte Asyncify suspension stack. Compile commands were checked for the requested optimization and exception mode; LTO objects were checked for LLVM bitcode.

All 24 page modules completed once under Node, reporting status zero and exactly cobalt slept. The -O2 modules also passed in local HeadlessChrome 153.0.8010.12 under both suspension variants and both exception modes. The other optimization profiles were not individually tested in Chrome. These are complete modules, including the Cobalt runner and the selected library code, without the Node test harness. Sizes are uncompressed bytes; JavaScript excludes the shared loader and HTML. Add the matching Wasm and JavaScript columns for the two-file payload. These measurements do not isolate the size added by Cobalt and are not runtime-memory measurements.

Table 2. asio_cobalt: uncompressed release bytes
Flags Exceptions JSPI Wasm Asyncify Wasm JSPI JavaScript Asyncify JavaScript

-O2

on

106,576

217,448

79,879

91,502

-O2

off

89,343

144,979

79,917

84,340

-O3

on

107,528

212,837

79,480

90,057

-O3

off

88,619

141,357

79,074

83,007

-Os

on

95,141

199,988

79,480

89,676

-Os

off

78,139

133,278

79,074

83,007

-Oz

on

87,956

196,771

78,909

89,103

-Oz

off

73,602

134,390

78,503

82,436

-O3 -flto

on

113,033

193,297

80,690

90,115

-O3 -flto

off

88,243

132,345

80,684

83,628

-Oz -flto

on

82,107

163,883

80,119

89,544

-Oz -flto

off

70,016

123,353

80,113

83,057

To measure the corresponding example in the current distribution, run from the superproject root. This produces new results; it does not reproduce the old source revision or certify the historical numbers below:

b2 -a -j4 --build-dir=bin/cobalt-size-oz-lto-on \
    toolset=emscripten variant=release exception-handling=on \
    "cxxflags=-Oz -flto" "linkflags=-Oz -flto" \
    libs/cobalt/example//page-asio_cobalt.variants.json

Use the profiles in How to compare release sizes and timings and a separate build directory for each profile and exception mode. Use the Cobalt example’s generated size report for new results. These single builds establish file sizes and successful execution; they do not supply repeated build-time or execution-time benchmarks. Task 14’s timing tables remain measurements of its original three examples, without Cobalt.

Sockets and transports

Explanation: native sockets and browser capabilities

Native builds use Boost.Asio’s socket types directly. Emscripten builds use webcpp protocol and socket templates with the supported Boost signatures. They do not call SOCKFS or invent IP addresses through getaddrinfo. Browser TCP and UDP are unavailable unless a transport supplies the operations.

With the default transport, opening and closing an object succeeds without acquiring a network resource. Opening an already open object reports already_open. With the default transport, network operations return operation_not_supported: synchronous calls return immediately, and asynchronous calls post their completion. These browser adapters offer error_code& overloads; their throwing overloads are present only with exceptions enabled. Native and WASI overload sets retain upstream semantics. Queries such as is_open describe the local object.

How-to: provide a transport

Specialize browser::transport<Protocol> for a protocol to provide its network operations. The specialization must be visible before first use in every translation unit using that protocol. A relay is a separate transport, not a change to an individual socket’s error policy. Its close() must cancel pending operations, release connection resources and return an error_code; the socket forwards closure and marks itself closed on success. Destruction must release resources as well. Move operations must transfer resources while preserving a usable executor in the source, so a moved-from socket can be reopened. Boost.Beast’s tcp_stream contains a Boost socket; a relay reaches Beast as an explicitly named next layer.

Reference: supported operations

Stream sockets support connect, read/write_some, send/receive, shutdown, options, endpoint queries and non-blocking settings. Datagram sockets add bind, send_to and receive_from. Acceptors support bind, listen and accept, including asynchronous acceptance into an existing or returned socket. Callbacks and deferred tokens use the same asynchronous initiation. See [asio-invariant-12] and the generated API reference for overloads.

Tutorial: observe an unsupported connection

Build and run asio_sockets on Emscripten. The object opens locally; connecting reports a value without attempting a network connection. Closing succeeds.

#include <cstdio>
#include <webcpp/asio/io_context.hpp>
#include <webcpp/asio/ip/tcp.hpp>
#include <webcpp/test/exit_status.hpp>

int main() {
    webcpp::asio::io_context io;
    webcpp::asio::ip::tcp::socket socket(io);
    boost::system::error_code ec;
    int failures = 0;
    const auto open_result = socket.open(webcpp::asio::ip::tcp::v4(), ec);
    const bool opened = !open_result && !ec && socket.is_open();
    std::printf("open: %s\n", opened ? "true" : "false");
    failures += static_cast<int>(!opened);
    const auto connect_result = socket.connect({webcpp::asio::ip::address_v4::loopback(), 80}, ec);
    const bool unsupported =
        connect_result == ec && ec == webcpp::asio::error::operation_not_supported;
    std::printf("connect: %s\n", unsupported ? "operation_not_supported" : "unexpected");
    failures += static_cast<int>(!unsupported);
    const auto close_result = socket.close(ec);
    const bool closed = !close_result && !ec && !socket.is_open();
    std::printf("close: %s\n", closed ? "ok" : "unexpected");
    failures += static_cast<int>(!closed);
    return webcpp::test::exit_status(failures);
}

Expected output:

open: true
connect: operation_not_supported
close: ok

Explanation: the resolver preserves names

On Emscripten, forward resolution constructs one entry with the original host and service, an unspecified IPv4 address and the service port. This is not a DNS lookup. A browser stream can retain the name without rewriting a client’s resolve step. A plain socket still refuses connecting to this entry.

An empty service means port 0. Decimal services accept 0 through 65535; http and ws select 80, and https and wss select 443. Named services are refused with numeric_service. Other services report service_not_found. Reverse resolution reports operation_not_supported. Async completion is posted; cancel does not retract a result already computed at initiation. See 13. Resolver entries preserve host and service.

Tutorial: retain a WebSocket service name

Build and run asio_resolver on Emscripten. The callback receives the retained name and service, port 443, and an unspecified address.

#include <cstdio>
#include <webcpp/asio/io_context.hpp>
#include <webcpp/asio/ip/tcp.hpp>
#include <webcpp/test/exit_status.hpp>

int main() {
    webcpp::asio::io_context io;
    webcpp::asio::ip::tcp::resolver resolver(io);
    int failures = 0;
    resolver.async_resolve(
        "example.com", "wss", [&](boost::system::error_code ec, const auto& results) {
            if (ec || results.size() != 1) {
                ++failures;
                return;
            }
            const auto& entry = *results.begin();
            const auto endpoint = entry.endpoint();
            std::printf("%s %s %u unspecified: %s\n", entry.host_name().c_str(),
                        entry.service_name().c_str(), static_cast<unsigned>(endpoint.port()),
                        endpoint.address().is_unspecified() ? "true" : "false");
        });
    io.run();  // lint-run: main waits for the posted resolver result
    return webcpp::test::exit_status(failures);
}

Expected output:

example.com wss 443 unspecified: true

Explanation: TLS settings

Native ssl names are the actual Boost types. WASIp2/P3 select the shipped, namespace-isolated Asio SSL backend. Both require OpenSSL explicitly linked as described in TLS: build OpenSSL from source on native and WASI. In the browser, ssl::context records method, verification, options, additional roots and client-credential requests. It does not read files, parse certificates, implement TLS or execute verification callbacks. A browser stream adapter must check this record against its capabilities before use; recording a request successfully does not mean the browser honors it. The webcpp::beast browser integration consumes these settings.

A host_name_verification request owns its input string. The context copies that name into its own std::pmr::string, using the resource given to its constructor. The allocation test verifies that recorded copy separately from the request object’s standard string allocation. Other callbacks record the other kind and clear a previously recorded host.

Tutorial: configure peer verification on both targets

Build and run the tls example. Natively this configures an OpenSSL context; on Emscripten it records the same request for a browser adapter.

#include <cstdio>
#include <webcpp/asio/ssl.hpp>
#include <webcpp/test/exit_status.hpp>

int main() {
    webcpp::asio::ssl::context context(webcpp::asio::ssl::context::tlsv12_client);
    context.set_verify_mode(webcpp::asio::ssl::verify_peer);
    std::puts("context: tlsv12_client, verify_peer");
    return webcpp::test::exit_status(0);
}

Expected output on either target:

context: tlsv12_client, verify_peer

Allocation

The application supplies an allocator to the io_context through its std::allocator_arg constructor. Boost.Asio uses it for the context’s services and their I/O state. On Emscripten the bridge’s registration map uses the context’s allocator too. Native types use unmodified Boost.Asio, including its platform-specific allocation limitations. In Boost 1.92 the Windows IOCP worker and lazy timer thread do not forward the context allocator for all of their state. The earlier WebCPP Windows patch is not selected by this distribution. Native identity does not establish an all-platform zero global-allocation guarantee.

An asynchronous operation uses its completion handler’s associated allocator. Giving an allocator to the context does not associate it with all handlers: bind it to each operation with webcpp::asio::bind_allocator. The following compiled test binds a timer wait and ten posts, and on Emscripten the handlers posted by two bridge deliveries:

void context_operations_use_the_supplied_allocator() {
    std::size_t given = 0;
    std::size_t posted = 0;
    std::size_t timed = 0;
    bool timer_succeeded = false;
#ifdef __EMSCRIPTEN__
    std::size_t received = 0;
    std::size_t promised = 0;
    std::size_t events = 0;
    std::size_t connected = 0;
    bool values_correct = true;
#endif
    {
        const allocation_window window;
        webcpp::asio::io_context io(std::allocator_arg, counted<void>(&given));
        webcpp::asio::steady_timer timer(io, std::chrono::milliseconds(5));
        timer.async_wait(
            webcpp::asio::bind_allocator(counted<void>(&given), [&](boost::system::error_code ec) {
                ++timed;
                timer_succeeded = !ec;
            }));
        for (std::size_t i = 0; i < 10; ++i) {
            webcpp::asio::post(
                io, webcpp::asio::bind_allocator(counted<void>(&given), [&posted] { ++posted; }));
        }
#ifdef __EMSCRIPTEN__
        webcpp::asio::ip::tcp::socket socket(io);
        socket.async_connect(
            {webcpp::asio::ip::address_v4::loopback(), 80},
            webcpp::asio::bind_allocator(counted<void>(&given), [&](boost::system::error_code ec) {
                ++connected;
                values_correct =
                    values_correct && ec == webcpp::asio::error::operation_not_supported;
            }));
        counted_registration listener(io, &given, &received);
        auto& bridge = webcpp::asio::use_service<webcpp::asio::browser::bridge>(io);
        const std::uint64_t key = bridge.add(listener);
        const emscripten::val deliver = bridge.function(key);
        deliver(1);
        deliver(2);
        const auto target = emscripten::val::global("EventTarget").new_();
        webcpp::asio::browser::async_wait_event(
            io.get_executor(), target, "message",
            webcpp::asio::bind_allocator(counted<void>(&given),
                                         [&](boost::system::error_code ec, const emscripten::val&) {
                                             values_correct = values_correct && !ec;
                                             ++events;
                                         }));
        target.call<bool>("dispatchEvent",
                          emscripten::val::global("Event").new_(emscripten::val("message")));
        for (const bool rejected : {false, true}) {
            auto promise = emscripten::val::global("Promise").call<emscripten::val>(
                rejected ? "reject" : "resolve", 42);
            webcpp::asio::browser::async_await(
                io.get_executor(), promise,
                webcpp::asio::bind_allocator(
                    counted<void>(&given),
                    [&, rejected](boost::system::error_code ec, const emscripten::val& value) {
                        ++promised;
                        values_correct =
                            values_correct && value.as<int>() == 42 &&
                            (rejected ? ec == webcpp::asio::browser::error::promise_rejected : !ec);
                    }));
        }
#endif
        io.run();  // lint-run: the test's event loop
#ifdef __EMSCRIPTEN__
        bridge.remove(key);
#endif
    }
    report("supplied allocator", given);
    BOOST_TEST_EQ(posted, 10U);
    BOOST_TEST_EQ(timed, 1U);
    BOOST_TEST(timer_succeeded);
#ifdef __EMSCRIPTEN__
    BOOST_TEST_EQ(received, 2U);
    BOOST_TEST_EQ(promised, 2U);
    BOOST_TEST_EQ(events, 1U);
    BOOST_TEST_EQ(connected, 1U);
    BOOST_TEST(values_correct);
#endif
    BOOST_TEST_GT(given, 0U);
#if defined(WEBCPP_TARGET_NATIVE) && defined(BOOST_ASIO_HAS_IOCP)
    // Native identity retains Boost 1.92's IOCP timer-thread allocation.
    // This negative witness must stop passing when upstream fixes routing.
    BOOST_TEST_GT(operator_new_calls, 0U);
    std::puts(
        "UPSTREAM-LIMITATION: native Boost IOCP uses global new for thread state; "
        "this is not a zero-global-allocation result");
#else
    BOOST_TEST_EQ(operator_new_calls, 0U);
#endif
    BOOST_TEST_EQ(c_allocations, 0U);
    BOOST_TEST_EQ(aligned_allocations, 0U);
}

These are runtime objects, with executors, callbacks and pointers into the current process. None of asio’s runtime objects is a relocatable object that can be shared between processes merely by placing it in shared memory.

Runtime allocations

Failures while converting errors or parsing addresses

With compiler exceptions enabled, the shipped WebAssembly backend preserves the explicit error channels of these allocating utility functions:

  • disposition_traits<error_code>::to_exception_ptr captures a failure while constructing the system_error, including std::bad_alloc, in the returned exception pointer. A success error code still produces an empty pointer.

  • The string_view and error_code overloads of ip::make_address, ip::make_address_v4 and ip::make_address_v6 report error::no_memory when constructing their temporary string fails. Their declarations remain noexcept.

These are corrections to the shipped Wasm implementation. Native builds retain the original Boost 1.92 types and implementation, which can terminate on those allocation failures before the caller receives an error. With compiler exceptions disabled, allocation failure remains fatal; selecting an error_code overload does not make such a build recover from exhausted memory.

The browser allocation regression injects these failures before measuring stream allocations. Separate WASI probes exercise the same public functions. They do not establish recovery from every allocation failure in Asio or its runtimes.

Allocations outside handler routing

The allocator contract does not cover these known allocations outside an operation’s associated allocator:

  • Native Boost 1.92’s Windows IOCP worker and timer-thread state, as described above. A macOS allocation result does not validate the Windows backend.

  • Emscripten’s select allocates its poll array with calloc on each call.

  • Asyncify allocates its unwind data when a call suspends.

  • Boost.Asio’s basic_resolver_results allocates its result entries with new. The measured operation scenario above does not resolve a name. Forward asynchronous resolution owns copies of its input names through the initiating token’s associated allocator, preserving temporary input lifetimes. Bind the allocator when creating a deferred operation; binding one only when later launching it cannot retroactively change its already-owned input storage.

  • WASI libc allocates pipe descriptors and message storage for Asio’s wakeup pipe. The test attributes only calls creating that pipe and writes to its tracked writer descriptors, removes descriptors on close, and exercises a real pipe as a positive control. Ordinary user writes and allocations remain counted.

  • OpenSSL owns context, trust-store and cryptographic allocations. Its memory hooks are process-global and must be set before any OpenSSL allocation; an Asio context cannot install a per-operation allocator for other OpenSSL users.

The allocation test replaces Emscripten’s select in the test executable with a version whose poll array is on the stack. It marks only the call to Asyncify’s allocateData while it runs, restoring the flag even if it throws, and counts those runtime allocations separately. These are test instrumentation choices, not changes to allocations in a user’s program. JavaScript heap allocations are outside these WebAssembly-memory counters.

On macOS, dyld allocates the native thread-local storage of Asio’s thread-call-stack on its first access. Before measurement the test queries running_in_this_thread on a temporary context to initialize that thread runtime. The measured context and all its operations are then constructed anew inside the window. This measures allocation routing after thread runtime initialization, not the process’s cold-start memory usage.

What the test proves

allocation_native runs natively, with allocation_native_release also checking an optimized build; allocation joins the Node-based WebAssembly tests with JSPI and Asyncify, each with and without exceptions. allocation_wasip3 checks the single-thread profile with exceptions on/off; allocation_wasip3_threads checks the supported cooperative profile without exceptions through the threads lane. A counting allocator services context construction, a timer, ten posts and on Emscripten the bridge’s two event deliveries. The measurement includes object destruction. It requires allocations through the supplied allocator and zero calls through the other counted paths, excluding only the named runtime operations above, except on native Windows IOCP. There the same operation scenario is a negative witness for Boost 1.92’s documented thread-state defect: it requires observable global allocation and prints UPSTREAM-LIMITATION, while still checking the timer and every posted completion. It does not certify zero global allocation or impose an arbitrary allowance. A corrected upstream that removes the allocation fails this witness and requires reclassification. This checks allocation routing, not a total memory limit or a proof of freedom from leaks. A separate explicit suspension verifies Asyncify’s runtime attribution: the timer may already be ready when run starts and therefore need no suspension.

The counters observe all eight global operator new forms: scalar and array, ordinary and aligned, throwing and nothrow. They also observe the C library’s malloc, calloc, realloc, aligned_alloc, posix_memalign and memalign where the platform permits it. On glibc and Emscripten the replacements forward to the underlying allocator; on macOS malloc_logger observes allocations, including aligned ones, in the C counter. Only the test’s thread and measurement windows are counted on POSIX platforms. MSVC counts global operator new calls from all threads in each window. The native allocation tests use -fno-builtin with Clang and GCC so calls to allocation functions remain observable by the hooks and are not moved across their measurement flags. This setting is confined to the test; application builds and the release size measurements keep their normal optimizations.

MSVC and AddressSanitizer builds do not count C-library allocations; they print that limitation and omit the C-specific controls. Global allocations through operator new are still counted. Local validation on one platform does not establish the behaviour of the hooks on another.

Controls deliberately call the allocation functions and post an unbound handler. Asio’s default handler storage goes through an aligned allocation, which counting only operator new would miss. A separate negative run constructs the context without its allocator and must fail. There is no allowance for an arbitrary number of extra allocations.

Promise operations allocate their state through the handler’s allocator. The allocation test covers resolution and rejection with a concrete context executor and a bound allocator, including the completion post. Explicitly erasing an executor into any_io_executor can introduce Boost-owned dispatch allocations that its handler allocator does not control; see Promises and events.

The default browser socket transport preserves an ordinary context executor’s associated allocation policy even when stored as any_io_executor. The same measurement includes an unsupported asynchronous connection with a bound allocator. Custom executors, including strands, keep their own dispatch policy.

Guarantees

These contracts apply to the supported calls described in Who may call it. The numbered anchors are stable: code and tests link to the same guarantee when its explanation moves. The reference describes individual API members; these guarantees describe their behaviour together.

  1. Natively, io_context is an alias of Boost.Asio’s context, with its original constructors, executor type and run family. Browser scheduling options are not members of this native type. The timer aliases name Boost’s types. See The names; checked by names.

  2. On Emscripten, supported handler execution happens on the stack of a run family call from main or another export configured for suspension. Posted work and events delivered through the bridge wait for such a call. See Before run, and after main; checked by reactor and bridge.

  3. A turn runs at most max_handlers_per_turn handlers, counting both ready handlers and handlers completed by a wait. A full turn yields through a macrotask unless the context is stopped or its timed call has expired. Timed calls check deadlines before handlers; they cannot interrupt a running handler or guarantee when the host resumes them. See A turn at a time; checked by turn_limit, run_family and browser_render.

  4. A conforming bridge registration only posts completed work; it does not run or dispatch it inline. A listener alone is not outstanding work. See Browser events; checked by bridge.

  5. A bridge registration’s key is never reused. An event for a removed key or a destroyed context delivers nothing. The registration must outlive its key. See Browser events; checked by bridge.

  6. On Emscripten, a run family call on a context already running or delivering a bridge event reports an assertion violation and, if assertion handling permits execution to continue, returns zero without running work. It is also refused with assertions disabled. The detection scope and bypasses are listed in Who may call it; checked by detection.

  7. With exceptions enabled, a handler’s C++ exception propagates out of the run family as it does in Boost.Asio, natively and under both suspension variants. JavaScript errors have different rules. See Exceptions and JavaScript errors; checked by exceptions.

  8. Boost’s timers and Beast’s timeouts complete through the reactor on both targets. Timer cancellation retains Boost’s semantics, including cancellation of an individual wait through its associated slot. See Timers; checked by timers.

  9. Within the allocation scenarios and platform limits in Allocation, context services use the context’s allocator; operation storage uses the handler’s associated allocator. Supplying one does not implicitly supply the other. The named runtime allocations and measurement limits in Runtime allocations, including native Boost’s Windows IOCP limitation, remain outside that routing claim. See Allocation; checked by allocation.

  10. A Promise completes its operation through the bridge with its value, or with promise_rejected and its reason. Cancellation posts operation_aborted; a later settlement cannot complete it again. See Promises and events; checked by promise and promise_cobalt.

  11. A pending Promise or event operation owns outstanding work. Destroying the context destroys its pending handler without invoking it. An event wait also removes its listener. See Promises and events; checked by promise and event.

  12. On Emscripten, network operations on a socket or acceptor fail with operation_not_supported unless a transport supplies them. Open and close manage local state; synchronous failures never block and asynchronous failures are posted. See Sockets and transports; checked by sockets and transport.

13. Resolver entries preserve host and service

On Emscripten, forward resolution returns one entry containing the original host and service, an unspecified address and the service port. A plain socket cannot connect to it. resolver_test.cpp checks service parsing and posted completion, including failures.

Testing

How to test your application

For a small program with deterministic text output, follow the compiled examples: keep an .expected file beside its source and declare the program with webcpp.example in its example Jamfile. Run the native target first, then Emscripten with JSPI and Asyncify. Compare observable completions and error values; avoid exact elapsed-time assertions, since the host can resume a ready operation later than its deadline.

Keep the context and objects captured by handlers alive until their work finishes. A cancelled operation must still complete with its cancellation error; merely requesting cancellation does not prove that it was delivered. Use Tutorial: your first asynchronous program and How to schedule deadlines and cancel a wait as executable starting points. Native and Node runs do not establish browser rendering behaviour; use a real browser when your contract depends on page events or animation.

For resolver cancellation, distinguish a pending lookup from a result already delivered by poll_one(). A fast host may complete a localhost lookup during that first call; cancelling afterwards cannot retract the successful callback. The WASI resolver test accepts that ordering, and resolver_immediate repeats it with an immediately returned host result. resolver_progress separately holds a WASIp3 lookup pending and checks resolver-wide cancellation, per-operation cancellation, context shutdown and allocation release. It does not use localhost latency as proof that cancellation reached pending work.

Current maintained-example matrix

This table covers the nine maintained Asio guide programs, not every original Boost.Asio application. Each pass is a fresh Release build followed by an exact .expected output comparison. Emscripten observations here run in Node; the real-browser scheduling and worker tests are separate. The Cobalt alias is covered by the Cobalt application matrix.

Profile quick_start timers turn_limit promise event sockets resolver tls_client capabilities

native-single-on

pass

pass

n/a

n/a

n/a

n/a

n/a

pass

pass

native-single-off

pass

pass

n/a

n/a

n/a

n/a

n/a

pass

pass

native-multi-on

pass

pass

n/a

n/a

n/a

n/a

n/a

pass

pass

native-multi-off

pass

pass

n/a

n/a

n/a

n/a

n/a

pass

pass

wasip2-single-on

pass

pass

n/a

n/a

n/a

n/a

n/a

pass

pass

wasip2-single-off

pass

pass

n/a

n/a

n/a

n/a

n/a

pass

pass

wasip2-multi-on

SDK

SDK

SDK

SDK

SDK

SDK

SDK

SDK

SDK

wasip2-multi-off

SDK

SDK

SDK

SDK

SDK

SDK

SDK

SDK

SDK

wasip3-single-on

pass

pass

n/a

n/a

n/a

n/a

n/a

pass

pass

wasip3-single-off

pass

pass

n/a

n/a

n/a

n/a

n/a

pass

pass

wasip3-multi-on

SDK

SDK

SDK

SDK

SDK

SDK

SDK

SDK

SDK

wasip3-multi-off

pass

pass

n/a

n/a

n/a

n/a

n/a

pass

pass

jspi-single-on

pass

pass

pass

pass

pass

pass

pass

n/a

n/a

jspi-single-off

pass

pass

pass

pass

pass

pass

pass

n/a

n/a

jspi-multi-on

pass

pass

pass

pass

pass

pass

pass

n/a

n/a

jspi-multi-off

pass

pass

pass

pass

pass

pass

pass

n/a

n/a

asyncify-single-on

pass

pass

pass

pass

pass

pass

pass

n/a

n/a

asyncify-single-off

pass

pass

pass

pass

pass

pass

pass

n/a

n/a

asyncify-multi-on

pass

pass

pass

pass

pass

pass

pass

n/a

n/a

asyncify-multi-off

pass

pass

pass

pass

pass

pass

pass

n/a

n/a

n/a means this particular example demonstrates an interface belonging to another target. It is not a failed test. SDK records absent P2 pthread or P3 cooperative exception support in wasi-sdk 34. The browser socket example deliberately verifies operation_not_supported for raw TCP; the browser resolver preserves the hostname for a host transport rather than performing guest DNS. The TLS example constructs and validates a trust context; it does not itself exchange TLS traffic.

The 92 successful executions retain commands, log hashes and implementation snapshots in the accompanying application evidence. No remote CI result is inferred.

The shared Release comparison measures this shipped Asio implementation alongside Cobalt, including native, WASIp2/P3 and browser page/worker profiles. It separates payload size, startup, execution and instrumented memory. The Yield measurements of the shipped implementation isolates browser handoff cost. Older measurements below remain evidence for their recorded source and environment, rather than measurements of the current migration.

What the library checks

asio’s tests are under test/, each declared in test/Jamfile with webcpp’s rules, for native, emscripten, wasip2 and wasip3: 251 tests in all, 91 natively, 174 on emscripten, run by node, 39 on WASIp2, and 95 on WASIp3. The WASI profiles and local commands are in Build for WASIp2 and Build and test a WASIp3 program. Each public header is also compiled alone, as the only include of its translation unit, so that a header that leans on an include it does not make fails, naming it.

<webcpp/asio/config.hpp>, which every public header of asio includes first, defines WEBCPP_ASIO_NO_EXCEPTIONS when the build has no exceptions, and a program may define it explicitly for WebCPP-owned adapters. Browser throwing overloads follow that policy. Native Boost and upstream-derived WASI APIs retain their overload sets; an error through a throwing overload can reach the fatal handler when compiler exceptions are disabled. The tests config, config_developer_defined and config_all_off check compiler, library-specific and global WebCPP settings.

The lanes

In addition to the WASIp2/P3 targets above, asio declares these lanes for the build and test matrix, each built from scratch with b2 -a and a --build-dir of its own. From the root of a webcpp checkout:

native

Every test and example, natively:

b2 libs/asio/test libs/asio/example
emscripten

The same on emscripten, in the default suspension variant, JSPI, each program run by node:

b2 toolset=emscripten libs/asio/test libs/asio/example
asyncify

A lane of asio’s own, on emscripten: every browser test again under Asyncify, the other suspension variant. Generate the size table separately in optimized release mode, then execute the guide examples under Asyncify:

b2 toolset=emscripten libs/asio/test//asyncify
b2 -a toolset=emscripten variant=release linkflags=-O3 libs/asio/example//asyncify
b2 toolset=emscripten webcpp-suspend=asyncify libs/asio/example
browser

A lane of asio’s own, on emscripten: the loader that picks a variant, under node, and in headless Chrome a page program that never polls, a page that keeps rendering, and the variant the loader picks:

b2 toolset=emscripten libs/asio/test/browser//browser
cobalt

An exact-exit driver runs the Cobalt entry point with statuses 7 and 0, with exceptions on and off, natively and under JSPI. A trap cannot count as the expected nonzero status:

b2 libs/asio/test//cobalt
b2 toolset=emscripten libs/asio/test//cobalt
cobalt_asyncify

The same exact-exit driver under Asyncify. It is also included in the asyncify test lane:

b2 toolset=emscripten libs/asio/test//cobalt_asyncify

b2 libs/asio/test//config builds and runs one test alone, while working on it.

Browser observations

browser_idle, browser_render and browser_loader run real page programs in headless Chrome, on both JSPI and Asyncify. The driver serves only its page, loader and build artifacts on loopback HTTP. Set CHROME to the browser executable; on macOS it otherwise finds the newest installed Playwright headless shell. Each driver has a 120-second outer bound and removes its Chrome process and temporary profile on success, failure or a termination signal.

An idle context with outstanding work must schedule exactly one positive setTimeout, at most 300 seconds, during a three-second observation. Calls to setInterval and MessagePort.postMessage are recorded too, so repeated polling cannot pass as a wait.

A self-posting handler runs for one second. The bounded run must allow at least ten animation callbacks; Boost’s unbounded control must allow none between the program’s start and completion. Callback entry times use performance.now(), not the frame timestamp supplied by requestAnimationFrame. This observes animation opportunities, not individual painted pixels or a universal frame-rate guarantee.

The yield’s MessageChannel records each complete turn at the configured limit, from resumption to the next post. The first starts at the program’s spinning line; the final partial turn is not a full-lot sample. Three historical runs at limit 1000 record callback and handler counts, turn counts, p95 and maximum turn duration in the library’s AGENTS.md. A p95 above 8 ms in either variant stops the task for the owner to decide the default. A run with no animation callbacks also stops for a decision about the witness. The maximum is reported separately. Heavy individual handlers can still block the page regardless of the handler-count limit.

The loader check runs the three-handler page normally and again after removing WebAssembly.Suspending before navigation. The page identifies the actual imported URL against the manifest before awaiting its factory, so a JSPI program whose main never returns can still report its variant. Any page exception, console.error or recorded loader error fails the run.

The test matrix

Each lane records what b2 built and ran, and webcpp’s tools/report/report.py merges the records of every lane into a matrix: a page of the libraries by lanes, and a page of each library’s tests and examples by lanes, where each cell says whether that program passed in that lane, or how it failed, at compile time, at link time or when it ran. The matrix is published with the documentation, at https://webcpporg.github.io/webcpp/report/.

How to compare release sizes and timings

Published binary sizes always use release builds. Compare the same page programs under six optimization profiles, with exceptions both enabled and disabled. Each command builds JSPI and Asyncify. Run from the superproject root, keeping the suspension-stack size and toolchain fixed:

for profile in o2 o3 os oz o3-lto oz-lto; do
    case "$profile" in
        o2) flags="-O2" ;;
        o3) flags="-O3" ;;
        os) flags="-Os" ;;
        oz) flags="-Oz" ;;
        o3-lto) flags="-O3 -flto" ;;
        oz-lto) flags="-Oz -flto" ;;
    esac
    for exceptions in on off; do
        b2 -a -j4 "--build-dir=bin/asio-size-$profile-$exceptions" \
            toolset=emscripten variant=release \
            "exception-handling=$exceptions" \
            "cxxflags=$flags" "linkflags=$flags" \
            libs/asio/example//asyncify
    done
done

variant=release supplies NDEBUG and disables debug symbols. The explicit cxxflags selects the optimization level instead of the release default -O3; the same level must be passed through linkflags for Emscripten’s final WebAssembly and JavaScript optimization. The current b2 toolset does not forward it automatically. Keep separate build directories: free-form flags do not select separate output paths in b2.

-O2 and -O3 favor execution performance; -Os and -Oz favor smaller code. -flto enables link-time optimization across translation units and must be used when compiling their object files as well as when linking. Neither a size-oriented level nor LTO guarantees a smaller result in every program.

With exception-handling=on, JSPI uses WebAssembly exceptions (-fwasm-exceptions) and Asyncify uses JavaScript-based exceptions (-fexceptions). With off, objects use -fno-exceptions, neither exception mechanism is enabled at link, and Boost’s no-exception handler is linked. The programs do not throw: this compares the cost of enabling exception support on their normal path, not throw/catch latency. Disabling exceptions changes error behavior; select it only when that contract fits the application.

Binary sizes

Each build prints its Wasm table and writes asio.sizes.md beside the variant manifests. The manifests record the Wasm byte counts; the JavaScript columns below measure the corresponding scripts themselves. These are complete page modules without the Node test harness, not asio’s isolated contribution. Add the matching Wasm and JavaScript columns for the two-file uncompressed payload. Compression, loader/HTML assets, HTTP overhead and runtime memory are outside these measurements.

The following task 14 tables cover the three examples listed below. The current command also builds the later Cobalt example; its separate measurements are in Historical reference: release binary sizes.

Measured on 2026-10-14 with Emscripten 6.0.11, Boost 1.92 and C++20, Node 26.7.0, macOS 27 arm64, Apple M5 Max, 128 GiB RAM. Asyncify uses an 8192-byte suspension stack. All values below are bytes. Every configuration was rebuilt in four fresh directories: one preparation build and three measured builds. File sizes were identical across the four builds. Compile and link commands were checked for optimization and exception settings; LTO object files were checked to contain LLVM bitcode. All 72 page modules matched their expected output and signalled successful completion in each runtime round. This validates these examples under Node, not the full library suite or real browsers under every profile.

Table 3. asio_quick_start: uncompressed bytes
Flags Exceptions JSPI Wasm Asyncify Wasm JSPI JavaScript Asyncify JavaScript

-O2

on

81,162

157,410

79,404

90,706

-O2

off

64,051

101,265

79,442

83,865

-O3

on

80,979

153,459

78,899

89,248

-O3

off

62,446

97,040

78,493

82,499

-Os

on

74,490

147,893

78,899

88,867

-Os

off

57,213

94,893

78,493

82,499

-Oz

on

70,771

148,813

78,328

88,296

-Oz

off

55,822

97,682

77,922

81,928

-O3 -flto

on

86,096

143,667

79,747

89,240

-O3 -flto

off

62,925

92,583

79,341

83,036

-Oz -flto

on

65,712

127,067

79,176

88,871

-Oz -flto

off

52,861

90,073

78,770

82,465

Table 4. asio_timers: uncompressed bytes
Flags Exceptions JSPI Wasm Asyncify Wasm JSPI JavaScript Asyncify JavaScript

-O2

on

82,969

162,160

79,394

90,696

-O2

off

66,110

106,196

79,432

83,855

-O3

on

82,724

157,831

78,889

89,238

-O3

off

64,738

102,226

78,483

82,489

-Os

on

74,987

150,501

78,889

88,857

-Os

off

57,592

97,281

78,483

82,489

-Oz

on

72,022

153,293

78,318

88,286

-Oz

off

57,047

101,572

77,912

81,918

-O3 -flto

on

87,840

148,668

79,737

89,496

-O3 -flto

off

65,222

97,809

79,331

83,026

-Oz -flto

on

67,968

132,768

79,166

89,386

-Oz -flto

off

54,966

94,870

78,760

82,455

Table 5. asio_turn_limit: uncompressed bytes
Flags Exceptions JSPI Wasm Asyncify Wasm JSPI JavaScript Asyncify JavaScript

-O2

on

78,205

149,904

79,402

90,704

-O2

off

61,386

95,829

79,440

83,863

-O3

on

78,085

146,529

78,897

89,246

-O3

off

59,860

91,775

78,491

82,497

-Os

on

71,052

139,673

78,897

88,661

-Os

off

54,219

88,489

78,491

82,497

-Oz

on

67,838

141,185

78,326

88,090

-Oz

off

53,031

91,253

77,920

81,926

-O3 -flto

on

83,189

136,877

79,745

89,238

-O3 -flto

off

60,291

87,248

79,339

83,034

-Oz -flto

on

62,824

120,140

79,174

89,104

-Oz -flto

off

50,151

83,722

78,768

82,463

In this matrix, -Oz -flto produced the smallest Wasm modules and combined Wasm-plus-JavaScript payloads, with exceptions on or off. Removing exception support reduced Wasm and the combined payload in every matched configuration. For JSPI at -O2, JavaScript alone grew by 38 bytes without exceptions; it shrank in the other matched configurations. Without LTO, Asyncify’s -Os Wasm modules with exceptions were smaller than its -Oz modules. LTO with -O3 increased the JSPI Wasm size with exceptions. Rebuild and test an application’s own candidates before selecting a profile.

Build duration

Each sample is elapsed wall time for the task 14 b2 invocation with -a -j4: compilation, linking the six page modules of the three examples above, and writing their manifests and size table. Cobalt was not registered then and is excluded from these timings; the current command builds it too. It is not a time per example or per suspension variant. One complete preparation pass populated Emscripten’s system-library cache for all profiles and exception settings. The next three passes used new output directories, alternated configuration order, and ran one b2 process at a time. The table gives the median and observed minimum to maximum, in seconds. Downloads and the preparation pass are excluded. No runtime measurements ran concurrently with compilation. These are local observations; the host was not reserved against other system activity.

Flags Exceptions on: median (min to max), s Exceptions off: median (min to max), s

-O2

3.33 (3.29 to 3.37)

3.16 (3.13 to 3.18)

-O3

4.08 (4.04 to 4.09)

3.60 (3.57 to 3.69)

-Os

3.93 (3.92 to 3.99)

3.58 (3.52 to 3.58)

-Oz

3.93 (3.92 to 3.94)

3.51 (3.48 to 3.59)

-O3 -flto

4.71 (4.71 to 4.75)

4.17 (4.14 to 4.18)

-Oz -flto

4.46 (4.45 to 4.46)

4.01 (4.00 to 4.04)

Module initialization and example execution

Each sample used a fresh Node process and the exact page artifacts measured above. The runner imported the generated JavaScript and read the Wasm file before starting its clock. Initialization is measured from calling the module factory to onRuntimeInitialized; it excludes Node startup, JavaScript import/parsing, disk reads and network transfer. Execution is measured from that callback to the example’s explicit webcppTestFinished(0) signal. That signal occurs just before returning from main, before local-object cleanup. The runner waits for both the factory and the completion signal, so an Asyncify suspension cannot end a sample prematurely. It checks status zero, a single completion, exact .expected output and no stderr.

One runtime round was discarded, followed by eleven measured rounds per module, reversing configuration order between rounds. Each sample still starts a fresh process: this is not a warmed-JIT or steady-state benchmark. The tables report the median in milliseconds. Parentheses contain the 25th to 75th percentiles, calculated by linear interpolation of sorted samples. This spread describes observed variability, not a confidence interval.

The quick-start example deliberately waits 50 ms. The timers example waits until its 60 ms deadline, then tests cancellation. The turn-limit example runs 5,000 handlers with a budget of 250 per turn and yields to the event loop. Execution includes these waits, scheduling and compilation performed lazily by the runtime. None of these values is CPU-only throughput, and small differences are not evidence that a flag makes application code faster.

Table 6. asio_quick_start: median (25th to 75th percentiles), ms
Flags Exceptions JSPI init JSPI execution Asyncify init Asyncify execution

-O2

on

3.48 (3.42 to 3.52)

53.33 (52.83 to 53.80)

3.16 (3.13 to 3.20)

54.66 (54.63 to 54.76)

-O2

off

3.39 (3.33 to 3.44)

53.53 (53.32 to 53.64)

2.91 (2.77 to 3.05)

53.97 (53.53 to 54.08)

-O3

on

3.40 (3.33 to 3.49)

53.68 (53.11 to 53.83)

3.07 (2.93 to 3.18)

54.59 (54.47 to 54.66)

-O3

off

3.40 (3.31 to 3.47)

52.79 (52.64 to 53.47)

2.90 (2.86 to 2.91)

54.01 (53.45 to 54.16)

-Os

on

3.38 (3.29 to 3.43)

53.47 (52.79 to 53.81)

3.10 (2.95 to 3.17)

54.64 (54.40 to 54.73)

-Os

off

3.37 (3.27 to 3.44)

53.48 (53.12 to 53.64)

2.86 (2.77 to 2.89)

53.82 (53.12 to 54.10)

-Oz

on

3.44 (3.31 to 3.47)

53.64 (52.80 to 53.73)

3.09 (3.02 to 3.17)

54.53 (54.45 to 54.82)

-Oz

off

3.36 (3.33 to 3.43)

53.61 (53.47 to 53.67)

2.89 (2.76 to 2.97)

54.07 (53.79 to 54.26)

-O3 -flto

on

3.51 (3.41 to 3.56)

53.75 (53.60 to 53.87)

3.06 (2.94 to 3.14)

53.64 (53.46 to 54.46)

-O3 -flto

off

3.37 (3.33 to 3.40)

53.48 (52.78 to 53.58)

2.85 (2.76 to 2.99)

53.90 (52.95 to 53.99)

-Oz -flto

on

3.43 (3.31 to 3.46)

53.61 (53.13 to 53.69)

3.04 (2.90 to 3.11)

54.39 (54.33 to 54.47)

-Oz -flto

off

3.35 (3.24 to 3.40)

53.39 (52.95 to 53.50)

2.87 (2.75 to 2.92)

54.07 (53.87 to 54.13)

Table 7. asio_timers: median (25th to 75th percentiles), ms
Flags Exceptions JSPI init JSPI execution Asyncify init Asyncify execution

-O2

on

3.35 (3.18 to 3.43)

63.09 (62.99 to 63.13)

3.13 (3.11 to 3.18)

64.20 (64.15 to 64.27)

-O2

off

3.22 (3.19 to 3.47)

62.93 (62.86 to 62.98)

2.96 (2.94 to 3.07)

63.61 (63.41 to 63.66)

-O3

on

3.28 (3.22 to 3.40)

63.09 (63.02 to 63.21)

3.15 (3.11 to 3.16)

64.10 (64.05 to 64.16)

-O3

off

3.27 (3.21 to 3.39)

62.94 (62.86 to 63.05)

2.98 (2.97 to 3.02)

63.65 (63.35 to 63.74)

-Os

on

3.39 (3.17 to 3.45)

62.95 (62.78 to 63.13)

3.14 (3.09 to 3.17)

64.12 (64.01 to 64.19)

-Os

off

3.19 (3.17 to 3.38)

62.85 (62.78 to 63.08)

2.93 (2.91 to 2.97)

63.53 (63.43 to 63.67)

-Oz

on

3.34 (3.26 to 3.40)

63.11 (63.05 to 63.13)

3.16 (3.08 to 3.18)

64.18 (63.99 to 64.30)

-Oz

off

3.21 (3.19 to 3.46)

62.84 (62.40 to 63.05)

2.98 (2.90 to 2.99)

63.66 (63.58 to 63.68)

-O3 -flto

on

3.29 (3.28 to 3.49)

63.02 (62.95 to 63.12)

3.13 (3.11 to 3.19)

63.94 (63.78 to 64.01)

-O3 -flto

off

3.29 (3.23 to 3.40)

62.98 (62.79 to 63.22)

2.94 (2.92 to 2.98)

63.44 (63.36 to 63.56)

-Oz -flto

on

3.27 (3.21 to 3.41)

63.09 (62.96 to 63.19)

3.15 (3.08 to 3.16)

63.90 (63.56 to 64.04)

-Oz -flto

off

3.33 (3.22 to 3.37)

63.00 (62.89 to 63.04)

2.92 (2.89 to 2.96)

63.56 (63.50 to 63.61)

Table 8. asio_turn_limit: median (25th to 75th percentiles), ms
Flags Exceptions JSPI init JSPI execution Asyncify init Asyncify execution

-O2

on

3.33 (3.28 to 3.45)

10.15 (10.06 to 10.48)

3.04 (2.94 to 3.18)

13.19 (12.78 to 13.67)

-O2

off

3.36 (3.20 to 3.41)

10.00 (9.77 to 10.25)

2.88 (2.80 to 3.00)

10.61 (10.33 to 11.04)

-O3

on

3.34 (3.17 to 3.43)

10.48 (9.95 to 10.55)

2.98 (2.95 to 3.21)

12.93 (12.83 to 13.56)

-O3

off

3.38 (3.16 to 3.42)

10.14 (9.75 to 10.33)

2.83 (2.76 to 3.04)

10.52 (10.21 to 11.06)

-Os

on

3.35 (3.20 to 3.44)

10.44 (10.00 to 10.51)

3.06 (2.96 to 3.09)

13.92 (13.14 to 14.07)

-Os

off

3.33 (3.16 to 3.41)

10.21 (9.86 to 10.41)

2.83 (2.78 to 2.98)

10.50 (10.32 to 11.05)

-Oz

on

3.39 (3.24 to 3.43)

10.94 (10.57 to 11.23)

2.97 (2.92 to 3.12)

14.33 (14.15 to 14.78)

-Oz

off

3.32 (3.18 to 3.41)

10.85 (10.51 to 11.05)

2.84 (2.77 to 2.98)

11.63 (11.52 to 12.40)

-O3 -flto

on

3.39 (3.21 to 3.45)

10.25 (9.85 to 10.43)

3.02 (2.94 to 3.13)

12.49 (12.23 to 13.04)

-O3 -flto

off

3.33 (3.19 to 3.37)

9.99 (9.73 to 10.22)

2.81 (2.73 to 2.94)

10.44 (10.19 to 11.00)

-Oz -flto

on

3.34 (3.21 to 3.39)

10.93 (10.46 to 11.06)

2.94 (2.90 to 3.11)

14.75 (14.21 to 14.96)

-Oz -flto

off

3.17 (3.09 to 3.19)

10.27 (10.10 to 10.34)

2.80 (2.74 to 2.99)

11.25 (11.07 to 11.86)

threads

The threads lane runs Cobalt worker/post/join, multiple Asio context runners and the WASIp3 allocator witness. The cooperative SDK profile uses exceptions off and remains distinct from simultaneous native CPU execution.

b2 -a libs/asio/test//threads
b2 -a toolset=clang-wasip3 libs/asio/test//threads
tls-integration

Real peers exercise trusted/rejected certificates, SNI, embedded/replacement roots and entropy failure. Cobalt TLS state, encrypted transfer cancellation, and shutdown errors/cancellation run in libs/cobalt/test/tls//tls-integration. Native single/multi profiles run with exceptions on/off; WASIp3 runs single with exceptions on/off and cooperative with exceptions off. The WASIp3 entropy control verifies that host randomness failure prevents random output and key generation. It does not measure entropy quality.

b2 -a libs/asio/test/tls//tls-integration
b2 -a toolset=clang-wasip3 libs/asio/test/tls//tls-integration

Reference

Macros

Name Description

WEBCPP_ASIO_BACKEND_DISABLE_THREADS

Disables internal thread support when the compiler has no pthread ABI.

WEBCPP_ASIO_BACKEND_HEADER

Selects an implementation header for internal use.

WEBCPP_ASIO_DEFAULT_MAX_HANDLERS_PER_TURN

The default number of ready handlers processed in one turn on Emscripten.

WEBCPP_ASIO_HANDLER_TYPE

Names the completion-handler type for a token and signature on the selected backend.

WEBCPP_ASIO_HAS_BROWSER_BRIDGE

1 when Emscripten supplies the JavaScript event and Promise bridge; otherwise 0.

WEBCPP_ASIO_HAS_BROWSER_WORKERS

1 for a pthread browser profile; isolation and worker availability are runtime facts.

WEBCPP_ASIO_HAS_CO_AWAIT

1 when the selected backend supports C++ coroutine completion tokens.

WEBCPP_ASIO_HAS_HOST_DNS

1 when the host supplies forward address lookup; it does not imply reverse DNS.

WEBCPP_ASIO_HAS_LOCAL_SOCKETS

1 when native Boost.Asio enables local sockets; otherwise 0.

WEBCPP_ASIO_HAS_OPENSSL_BACKEND

1 when this target can link the source-built OpenSSL provider; it does not select it.

WEBCPP_ASIO_HAS_REVERSE_DNS

1 for native reverse lookup; WASI’s address lookup interface is forward-only.

WEBCPP_ASIO_HAS_SERIAL_PORT

1 when native Boost.Asio enables serial ports; otherwise 0.

WEBCPP_ASIO_HAS_SIGNALS

1 when native Boost.Asio enables process signals; WASI and browser events are not signals.

WEBCPP_ASIO_HAS_SOCKET_BACKEND

1 when native or WASI socket APIs back TCP/UDP; grants and options remain runtime facts.

WEBCPP_ASIO_HAS_THREADS

1 when this Boost.Asio configuration enables threads, including cooperative threads.

WEBCPP_ASIO_HAS_WASI_STDIO

1 when the pollable WASIp2 CLI stream adapter is available; otherwise 0.

WEBCPP_ASIO_NO_EXCEPTIONS

Selects the exception-free interface of WebCPP-owned adapters.

webcpp::asio

Namespaces

Types

Name Description

basic_datagram_socket

A browser datagram socket whose operations use browser::transport.

basic_socket_acceptor

A browser socket acceptor whose operations use browser::transport.

basic_stream_socket

A browser stream socket whose operations use browser::transport.

io_context

Boost.Asio’s io_context, whose run family on emscripten suspends into the browser’s event loop and yields to it after every turn of max_handlers_per_turn handlers.

io_context_options

The options of an io_context.

Type Aliases

Name Description

basic_waitable_timer

Boost.Asio’s timer on Clock, Boost’s own: on emscripten it waits in the reactor’s timer queue, which the run family waits on.

Enums

Name Description

tls_context_error

Errors produced while preparing an independently owned TLS client context.

Functions

Name Description

make_error_code

Converts a TLS context preparation error to its stable error code.

make_tls_client_context

make_tls_client_context overloads

Using Declarations

Name Description

steady_timer

Boost.Asio’s timer on the monotonic clock, Boost’s own: on emscripten it waits in the reactor’s timer queue, which the run family waits on.

system_timer

Boost.Asio’s timer on the system’s wall clock, Boost’s own: on emscripten it waits in the reactor’s timer queue, which the run family waits on.

webcpp::asio::browser

Namespaces

Name

error

Types

Name Description

bridge

The io_context’s bridge: the JavaScript functions through which browser events reach it, each delivering to one registration by a key that is never reused.

intrusive_registration

A registration whose lookup node lives in its owner’s allocation.

main_thread_context

An execution context that posts C++ handlers onto the browser’s main runtime thread.

registration

What an event delivered through the bridge reaches: it posts, nothing else.

transport

How the sockets of Protocol reach the network in the browser, which gives them none: every operation fails with operation_not_supported.

Functions

Name Description

async_await

Asynchronously receives a JavaScript Promise’s value or rejection reason.

async_wait_event

Asynchronously receives the next event of type on a JavaScript EventTarget.

operator==

Compares the contexts owning two executors.

webcpp::asio::browser::error

Enums

Name Description

errors

Errors reported by browser operations; values are never reused.

Functions

Name Description

category

Returns the category shared by all browser operation errors.

make_error_code

Creates the error code corresponding to value.

Variables

Name Description

promise_rejected

A JavaScript Promise rejection.

webcpp::asio::browser::error::errors

Errors reported by browser operations; values are never reused.

Synopsis

enum class errors : int;

Members

Name Description

promise_rejected

The JavaScript Promise rejected; its reason is the completion value.

webcpp::asio::browser::error::category

Returns the category shared by all browser operation errors.

Synopsis

boost::system::error_category const&
category() noexcept;

Return Value

The category named webcpp.asio.

webcpp::asio::browser::error::make_error_code

Creates the error code corresponding to value.

Synopsis

boost::system::error_code
make_error_code(errors value) noexcept;

Return Value

Its code in category().

Parameters

Name Description

value

The browser error.

webcpp::asio::browser::error::promise_rejected

A JavaScript Promise rejection.

Synopsis

inline constexpr errors promise_rejected = errors::promise_rejected;

webcpp::asio::browser::bridge

The io_context’s bridge: the JavaScript functions through which browser events reach it, each delivering to one registration by a key that is never reused.

Synopsis

class bridge
    : public webcpp::asio_backend::execution_context::service

Description

A service of the io_context, made with its allocator by ::webcpp::asio_backend::use_service<bridge>(io), and shut down and destroyed with it. On emscripten alone.

Base Classes

Name Description

webcpp::asio_backend::execution_context::service

Member Functions

Name Description

bridge [constructor]

Constructors

~bridge [destructor] [virtual]

Destroys the bridge: its functions deliver nothing from now on.

operator=

Assignment operators

add

add overloads

delivering

Whether the bridge is delivering an event, which the run family refuses to run inside.

function

A JavaScript function that delivers its argument to the registration key.

remove

Removes the registration key, whose events find nothing from now on.

Static Data Members

Name Description

id

The service’s identity, which Boost.Asio keys services by.

Friends

Name Description

webcpp_asio_deliver

See Also

"Browser events", in the guide.

webcpp::asio::browser::bridge::bridge

Constructors

Synopses

Not copyable: the functions it made deliver to it by its address.

bridge(bridge const&) = delete;

Not movable: the functions it made deliver to it by its address.

bridge(bridge&&) = delete;

Constructs the bridge of context, with nothing registered.

explicit
bridge(webcpp::asio_backend::execution_context& context);

Parameters

Name Description

context

The io_context it serves.

webcpp::asio::browser::bridge::bridge

Not copyable: the functions it made deliver to it by its address.

Synopsis

bridge(bridge const&) = delete;

webcpp::asio::browser::bridge::bridge

Not movable: the functions it made deliver to it by its address.

Synopsis

bridge(bridge&&) = delete;

webcpp::asio::browser::bridge::bridge

Constructs the bridge of context, with nothing registered.

Synopsis

explicit
bridge(webcpp::asio_backend::execution_context& context);

Parameters

Name Description

context

The io_context it serves.

webcpp::asio::browser::bridge::~bridge

Destroys the bridge: its functions deliver nothing from now on.

Synopsis

virtual
~bridge() override;

webcpp::asio::browser::bridge::operator=

Assignment operators

Synopses

Not copy-assignable: the functions it made deliver to it by its address.

bridge&
operator=(bridge const&) = delete;

Not move-assignable: the functions it made deliver to it by its address.

bridge&
operator=(bridge&&) = delete;

webcpp::asio::browser::bridge::operator=

Not copy-assignable: the functions it made deliver to it by its address.

Synopsis

bridge&
operator=(bridge const&) = delete;

webcpp::asio::browser::bridge::operator=

Not move-assignable: the functions it made deliver to it by its address.

Synopsis

bridge&
operator=(bridge&&) = delete;

webcpp::asio::browser::bridge::add

add overloads

Synopses

Registers an owner-allocated node without allocating lookup storage.

[[nodiscard]]
uint64_t
add(intrusive_registration& r);

Registers r, which must stay alive until it is removed, done, or shut down.

[[nodiscard]]
uint64_t
add(registration& r);

Return Value

  • Its unique key, from the same sequence as ordinary registrations.

  • Its key: the first is 1, and none is ever given twice.

Note

The return value should not be discarded.

Parameters

Name Description

r

Unregistered node that remains alive until removal or shutdown.

webcpp::asio::browser::bridge::add

Registers an owner-allocated node without allocating lookup storage.

Synopsis

[[nodiscard]]
uint64_t
add(intrusive_registration& r);

Return Value

Its unique key, from the same sequence as ordinary registrations.

Note

The return value should not be discarded.

Parameters

Name Description

r

Unregistered node that remains alive until removal or shutdown.

webcpp::asio::browser::bridge::add

Registers r, which must stay alive until it is removed, done, or shut down.

Synopsis

[[nodiscard]]
uint64_t
add(registration& r);

Return Value

Its key: the first is 1, and none is ever given twice.

Note

The return value should not be discarded.

Parameters

Name Description

r

The registration.

webcpp::asio::browser::bridge::delivering

Whether the bridge is delivering an event, which the run family refuses to run inside.

Synopsis

[[nodiscard]]
bool
delivering() const;

Description

Tip: the bridge’s JavaScript functions count the deliveries in progress and put the count back however a delivery ends, a JavaScript error included, so that nothing in C++, which such an error may leave without running its destructors, keeps it.

Return Value

True while a function of the bridge delivers, an outer one around a nested one included.

Note

The return value should not be discarded.

webcpp::asio::browser::bridge::function

A JavaScript function that delivers its argument to the registration key.

Synopsis

[[nodiscard]]
emscripten::val
function(uint64_t key);

Description

Called once key is removed, once the io_context is destroyed, or once the runtime aborted, with Emscripten’s ABORT flag set, it does nothing.

Return Value

The function, to install as a listener or a promise’s reaction.

Note

The return value should not be discarded.

Parameters

Name Description

key

A key add returned.

webcpp::asio::browser::bridge::remove

Removes the registration key, whose events find nothing from now on.

Synopsis

void
remove(uint64_t key) noexcept;

Parameters

Name Description

key

A key add returned; one already removed is ignored.

webcpp::asio::browser::bridge::id

The service’s identity, which Boost.Asio keys services by.

Synopsis

inline static
webcpp::asio_backend::execution_context::id id;

webcpp::asio::browser::intrusive_registration

A registration whose lookup node lives in its owner’s allocation.

Synopsis

class intrusive_registration
    : public registration
    , public boost::intrusive::avl_set_base_hook<boost::intrusive::link_mode<boost::intrusive::auto_unlink>>

Description

The bridge indexes it without allocating memory. Remove it before destruction, exactly as for registration; it may not be registered in two bridges at once.

Base Classes

Name Description

registration

What an event delivered through the bridge reaches: it posts, nothing else.

boost::intrusive::avl_set_base_hook<boost::intrusive::link_mode<boost::intrusive::auto_unlink>>

Member Functions

Name Description

intrusive_registration [constructor] [deleted]

A registered node cannot be copied.

operator= [deleted]

A registered node cannot be assigned.

Protected Member Functions

Name Description

intrusive_registration [constructor]

Constructs an unregistered node.

~intrusive_registration [destructor]

Destroys an already removed node.

Friends

Name Description

webcpp::asio::browser::bridge

The io_context’s bridge: the JavaScript functions through which browser events reach it, each delivering to one registration by a key that is never reused.

webcpp::asio::browser::intrusive_registration::intrusive_registration

A registered node cannot be copied.

Synopsis

intrusive_registration(intrusive_registration const&) = delete;

webcpp::asio::browser::intrusive_registration::operator=

A registered node cannot be assigned.

Synopsis

intrusive_registration&
operator=(intrusive_registration const&) = delete;

webcpp::asio::browser::intrusive_registration::intrusive_registration

Constructs an unregistered node.

Synopsis

constexpr
intrusive_registration() = default;

webcpp::asio::browser::intrusive_registration::~intrusive_registration

Destroys an already removed node.

Synopsis

~intrusive_registration() = default;

webcpp::asio::browser::main_thread_context

An execution context that posts C++ handlers onto the browser’s main runtime thread.

Synopsis

class main_thread_context
    : public webcpp::asio_backend::execution_context

Description

Construct and destroy it on the main browser thread. Its executors may be copied to workers and used with post, dispatch, defer and bind_executor. Handlers execute in ordinary browser callbacks and must not suspend WebAssembly’s stack or call an io_context run family. JavaScript values remain on their owning thread: obtain DOM values inside the main handler, and exchange ordinary C++ data with worker contexts through their executors.

Destruction discards queued handlers without invoking them. As with an Asio context, the context must outlive every call that uses its executors. The Emscripten runtime must remain alive until pending work finishes. The SDK owns proxy-queue notification storage; handler storage uses the allocator supplied to the executor. If moving or invoking a callable throws, remaining queued callables and further queued submissions are discarded. The exception propagates to the browser’s callback boundary; this context does not promise queue recovery after such a failure.

Base Classes

Name Description

webcpp::asio_backend::execution_context

Types

Name Description

executor_type

A standard Asio executor for nonsuspending handlers on the browser main thread.

Member Functions

Name Description

main_thread_context [constructor]

Constructors

get_executor

Returns an executor that can safely be copied to workers.

webcpp::asio::browser::main_thread_context::executor_type

A standard Asio executor for nonsuspending handlers on the browser main thread.

Synopsis

class executor_type;

Member Functions

Name Description

executor_type [constructor]

Constructs an empty executor, usable only for assignment or comparison.

context

Returns the context, which must still be alive.

defer

Defers through the same main-thread queue as post.

dispatch

Dispatches inline on the browser main thread, otherwise posts.

on_work_finished

The browser runtime lifetime is controlled by the application.

on_work_started

The browser runtime lifetime is controlled by the application.

post

Posts without invoking inline, using allocator for pending handler storage.

Friends

Name Description

webcpp::asio::browser::main_thread_context

An execution context that posts C++ handlers onto the browser’s main runtime thread.

webcpp::asio::browser::operator==

Compares the contexts owning two executors.

webcpp::asio::browser::main_thread_context::executor_type::executor_type

Constructs an empty executor, usable only for assignment or comparison.

Synopsis

constexpr
executor_type() = default;

webcpp::asio::browser::main_thread_context::executor_type::context

Returns the context, which must still be alive.

Synopsis

[[nodiscard]]
main_thread_context&
context() const noexcept;

Return Value

The execution context owning this executor.

Note

The return value should not be discarded.

webcpp::asio::browser::main_thread_context::executor_type::defer

Defers through the same main-thread queue as post.

Synopsis

template<
    class Function,
    class Allocator>
void
defer(
    Function&& function,
    Allocator const& allocator) const;

Template Parameters

Name Description

Function

A nullary callable that does not suspend WebAssembly’s stack.

Allocator

A standard allocator for pending handler storage.

Parameters

Name Description

function

The callable.

allocator

The pending handler’s allocator.

webcpp::asio::browser::main_thread_context::executor_type::dispatch

Dispatches inline on the browser main thread, otherwise posts.

Synopsis

template<
    class Function,
    class Allocator>
void
dispatch(
    Function&& function,
    Allocator const& allocator) const;

Template Parameters

Name Description

Function

A nullary callable that does not suspend WebAssembly’s stack.

Allocator

A standard allocator for pending handler storage.

Parameters

Name Description

function

The callable.

allocator

The allocator used when dispatch must post.

webcpp::asio::browser::main_thread_context::executor_type::on_work_finished

The browser runtime lifetime is controlled by the application.

Synopsis

void
on_work_finished() const noexcept;

webcpp::asio::browser::main_thread_context::executor_type::on_work_started

The browser runtime lifetime is controlled by the application.

Synopsis

void
on_work_started() const noexcept;

webcpp::asio::browser::main_thread_context::executor_type::post

Posts without invoking inline, using allocator for pending handler storage.

Synopsis

template<
    class Function,
    class Allocator>
void
post(
    Function&& function,
    Allocator const& allocator) const;

Template Parameters

Name Description

Function

A nullary callable that does not suspend WebAssembly’s stack.

Allocator

A standard allocator for pending handler storage.

Parameters

Name Description

function

The callable.

allocator

The pending handler’s allocator.

webcpp::asio::browser::main_thread_context::main_thread_context

Constructors

Synopses

Constructs a queue on the browser’s main runtime thread.

Constructs a main-thread context whose Asio service storage uses allocator.

template<class Allocator>
main_thread_context(
    std::allocator_arg_t,
    Allocator const& allocator);

Template Parameters

Name Description

Allocator

A standard allocator for context-owned C++ state.

Parameters

Name Description

allocator

The allocator for context-owned C++ state. The Emscripten SDK allocates its own proxy queue and notifications separately. If a callback destroys this context, its allocator resource must remain alive until that callback returns and the retained queue control is released.

webcpp::asio::browser::main_thread_context::main_thread_context

Constructs a queue on the browser’s main runtime thread.

Synopsis

main_thread_context();

webcpp::asio::browser::main_thread_context::main_thread_context

Constructs a main-thread context whose Asio service storage uses allocator.

Synopsis

template<class Allocator>
main_thread_context(
    std::allocator_arg_t,
    Allocator const& allocator);

Template Parameters

Name Description

Allocator

A standard allocator for context-owned C++ state.

Parameters

Name Description

allocator

The allocator for context-owned C++ state. The Emscripten SDK allocates its own proxy queue and notifications separately. If a callback destroys this context, its allocator resource must remain alive until that callback returns and the retained queue control is released.

webcpp::asio::browser::main_thread_context::get_executor

Returns an executor that can safely be copied to workers.

Synopsis

[[nodiscard]]
executor_type
get_executor() noexcept;

Return Value

An executor submitting work to this context on the browser main thread.

Note

The return value should not be discarded.

webcpp::asio::browser::registration

What an event delivered through the bridge reaches: it posts, nothing else.

Synopsis

class registration;

Description

Its owner (an operation, a stream, a channel) allocates it as it chooses, adds it to the bridge, and removes it before destroying it.

Member Functions

Name Description

deliver [virtual]

Posts what event completes or notifies to the io_context.

shutdown [virtual]

The shutdown of the bridge’s io_context: destroys what is pending without calling it.

Protected Member Functions

Name Description

registration [constructor]

Constructors

~registration [destructor]

Destroys a registration, which only its owner does.

operator=

Copies a registration.

Derived Classes

Name Description

intrusive_registration

A registration whose lookup node lives in its owner’s allocation.

See Also

"Browser events", in the guide.

webcpp::asio::browser::registration::deliver

Posts what event completes or notifies to the io_context.

Synopsis

virtual
bool
deliver(emscripten::val const& event) = 0;

Description

It never polls, runs or dispatches, and may free the registration when it returns true.

Return Value

Whether the registration is done, so that the bridge removes it.

Parameters

Name Description

event

The JavaScript value the event’s function was called with.

webcpp::asio::browser::registration::shutdown

The shutdown of the bridge’s io_context: destroys what is pending without calling it.

Synopsis

virtual
void
shutdown() noexcept = 0;

webcpp::asio::browser::registration::registration

Constructors

Synopses

Constructs a registration.

constexpr
registration() = default;

Copies a registration.

constexpr
registration(registration const&) = default;

webcpp::asio::browser::registration::registration

Constructs a registration.

Synopsis

constexpr
registration() = default;

webcpp::asio::browser::registration::registration

Copies a registration.

Synopsis

constexpr
registration(registration const&) = default;

webcpp::asio::browser::registration::~registration

Destroys a registration, which only its owner does.

Synopsis

constexpr
~registration() = default;

webcpp::asio::browser::registration::operator=

Copies a registration.

Synopsis

constexpr
registration&
operator=(registration const&) = default;

Return Value

This registration.

webcpp::asio::browser::transport

How the sockets of Protocol reach the network in the browser, which gives them none: every operation fails with operation_not_supported.

Synopsis

template<class Protocol>
class transport;

Description

A later library (relays that carry TCP or UDP over a WebSocket or a WebRTC channel) specialises it for a protocol; the specialisation is visible in every translation unit that uses the socket type, before its first use.

Type Aliases

Name Description

endpoint_type

The protocol endpoint type.

Member Functions

Name Description

transport [constructor]

Constructors

~transport [destructor]

Releases the transport state.

operator=

Assignment operators

accept

Reports the default transport result without accessing a network.

async_accept

Posts operation_not_supported without accessing a network.

async_connect

Posts operation_not_supported without accessing a network.

async_read_some

Posts operation_not_supported without accessing a network.

async_receive

Posts operation_not_supported without accessing a network.

async_receive_from

Posts operation_not_supported without accessing a network.

async_send

Posts operation_not_supported without accessing a network.

async_send_to

Posts operation_not_supported without accessing a network.

async_write_some

Posts operation_not_supported without accessing a network.

available

Reports the default transport result without accessing a network.

bind

Reports the default transport result without accessing a network.

cancel

Reports the default transport result without accessing a network.

close

Closes the resource-free default transport successfully.

connect

Reports the default transport result without accessing a network.

get_option

Reports the default transport result without accessing a network.

listen

Reports the default transport result without accessing a network.

local_endpoint

Reports the default transport result without accessing a network.

non_blocking

Reports the default transport result without accessing a network.

read_some

Reports the default transport result without accessing a network.

receive

Reports the default transport result without accessing a network.

receive_from

Reports the default transport result without accessing a network.

remote_endpoint

Reports the default transport result without accessing a network.

send

Reports the default transport result without accessing a network.

send_to

Reports the default transport result without accessing a network.

set_option

Reports the default transport result without accessing a network.

shutdown

Reports the default transport result without accessing a network.

write_some

Reports the default transport result without accessing a network.

Template Parameters

Name Description

Protocol

The protocol: ip::tcp or ip::udp.

webcpp::asio::browser::transport::endpoint_type

The protocol endpoint type.

Synopsis

using endpoint_type = Protocol::endpoint;

webcpp::asio::browser::transport::transport

Constructors

Synopses

Not copyable: a specialized transport may own a connection.

transport(transport const&) = delete;

Copies the executor so both transports remain usable after a move.

transport(transport&& other) noexcept;

Constructs an unsupported transport on executor.

explicit
transport(webcpp::asio_backend::any_io_executor executor);

Parameters

Name Description

other

The source transport.

executor

The executor.

webcpp::asio::browser::transport::transport

Not copyable: a specialized transport may own a connection.

Synopsis

transport(transport const&) = delete;

webcpp::asio::browser::transport::transport

Copies the executor so both transports remain usable after a move.

Synopsis

transport(transport&& other) noexcept;

Parameters

Name Description

other

The source transport.

webcpp::asio::browser::transport::transport

Constructs an unsupported transport on executor.

Synopsis

explicit
transport(webcpp::asio_backend::any_io_executor executor);

Parameters

Name Description

executor

The executor.

webcpp::asio::browser::transport::~transport

Releases the transport state.

Synopsis

~transport() = default;

webcpp::asio::browser::transport::operator=

Assignment operators

Synopses

Not copy-assignable: a specialized transport may own a connection.

transport&
operator=(transport const&) = delete;

Copies the executor, preserving the source transport.

transport&
operator=(transport&& other) noexcept;

Return Value

This transport.

Parameters

Name Description

other

The source transport.

webcpp::asio::browser::transport::operator=

Not copy-assignable: a specialized transport may own a connection.

Synopsis

transport&
operator=(transport const&) = delete;

webcpp::asio::browser::transport::operator=

Copies the executor, preserving the source transport.

Synopsis

transport&
operator=(transport&& other) noexcept;

Return Value

This transport.

Parameters

Name Description

other

The source transport.

webcpp::asio::browser::transport::accept

Reports the default transport result without accessing a network.

Synopsis

template<class Socket>
boost::system::error_code
accept(Socket&);

Return Value

operation_not_supported.

Template Parameters

Name Description

Socket

The operation argument type.

webcpp::asio::browser::transport::async_accept

Posts operation_not_supported without accessing a network.

Synopsis

template<
    class Socket,
    class Handler>
void
async_accept(
    Socket&,
    Handler&& handler);

Template Parameters

Name Description

Socket

The operation argument type.

Handler

The completion handler type.

Parameters

Name Description

handler

The handler to post with the unsupported-operation result.

webcpp::asio::browser::transport::async_connect

Posts operation_not_supported without accessing a network.

Synopsis

template<class Handler>
void
async_connect(
    endpoint_type const&,
    Handler&& handler);

Template Parameters

Name Description

Handler

The completion handler type.

Parameters

Name Description

handler

The handler to post with the unsupported-operation result.

webcpp::asio::browser::transport::async_read_some

Posts operation_not_supported without accessing a network.

Synopsis

template<
    class MutableBufferSequence,
    class Handler>
void
async_read_some(
    MutableBufferSequence const&,
    Handler&& handler);

Template Parameters

Name Description

MutableBufferSequence

The operation argument type.

Handler

The completion handler type.

Parameters

Name Description

handler

The handler to post with the unsupported-operation result.

webcpp::asio::browser::transport::async_receive

Posts operation_not_supported without accessing a network.

Synopsis

template<
    class MutableBufferSequence,
    class Handler>
void
async_receive(
    MutableBufferSequence const&,
    webcpp::asio_backend::socket_base::message_flags,
    Handler&& handler);

Template Parameters

Name Description

MutableBufferSequence

The operation argument type.

Handler

The completion handler type.

Parameters

Name Description

handler

The handler to post with the unsupported-operation result.

webcpp::asio::browser::transport::async_receive_from

Posts operation_not_supported without accessing a network.

Synopsis

template<
    class MutableBufferSequence,
    class Handler>
void
async_receive_from(
    MutableBufferSequence const&,
    endpoint_type&,
    webcpp::asio_backend::socket_base::message_flags,
    Handler&& handler);

Template Parameters

Name Description

MutableBufferSequence

The operation argument type.

Handler

The completion handler type.

Parameters

Name Description

handler

The handler to post with the unsupported-operation result.

webcpp::asio::browser::transport::async_send

Posts operation_not_supported without accessing a network.

Synopsis

template<
    class ConstBufferSequence,
    class Handler>
void
async_send(
    ConstBufferSequence const&,
    webcpp::asio_backend::socket_base::message_flags,
    Handler&& handler);

Template Parameters

Name Description

ConstBufferSequence

The operation argument type.

Handler

The completion handler type.

Parameters

Name Description

handler

The handler to post with the unsupported-operation result.

webcpp::asio::browser::transport::async_send_to

Posts operation_not_supported without accessing a network.

Synopsis

template<
    class ConstBufferSequence,
    class Handler>
void
async_send_to(
    ConstBufferSequence const&,
    endpoint_type const&,
    webcpp::asio_backend::socket_base::message_flags,
    Handler&& handler);

Template Parameters

Name Description

ConstBufferSequence

The operation argument type.

Handler

The completion handler type.

Parameters

Name Description

handler

The handler to post with the unsupported-operation result.

webcpp::asio::browser::transport::async_write_some

Posts operation_not_supported without accessing a network.

Synopsis

template<
    class ConstBufferSequence,
    class Handler>
void
async_write_some(
    ConstBufferSequence const&,
    Handler&& handler);

Template Parameters

Name Description

ConstBufferSequence

The operation argument type.

Handler

The completion handler type.

Parameters

Name Description

handler

The handler to post with the unsupported-operation result.

webcpp::asio::browser::transport::available

Reports the default transport result without accessing a network.

Synopsis

std::size_t
available(boost::system::error_code& ec) const;

Return Value

Zero.

Parameters

Name Description

ec

Receives operation_not_supported.

webcpp::asio::browser::transport::bind

Reports the default transport result without accessing a network.

Synopsis

boost::system::error_code
bind(endpoint_type const&);

Return Value

operation_not_supported.

webcpp::asio::browser::transport::cancel

Reports the default transport result without accessing a network.

Synopsis

boost::system::error_code
cancel();

Return Value

operation_not_supported.

webcpp::asio::browser::transport::close

Closes the resource-free default transport successfully.

Synopsis

boost::system::error_code
close() noexcept;

Return Value

Success.

webcpp::asio::browser::transport::connect

Reports the default transport result without accessing a network.

Synopsis

boost::system::error_code
connect(endpoint_type const&);

Return Value

operation_not_supported.

webcpp::asio::browser::transport::get_option

Reports the default transport result without accessing a network.

Synopsis

template<class GettableSocketOption>
boost::system::error_code
get_option(GettableSocketOption&) const;

Return Value

operation_not_supported.

Template Parameters

Name Description

GettableSocketOption

The operation argument type.

webcpp::asio::browser::transport::listen

Reports the default transport result without accessing a network.

Synopsis

boost::system::error_code
listen(int);

Return Value

operation_not_supported.

webcpp::asio::browser::transport::local_endpoint

Reports the default transport result without accessing a network.

Synopsis

endpoint_type
local_endpoint(boost::system::error_code& ec) const;

Return Value

An unspecified endpoint.

Parameters

Name Description

ec

Receives operation_not_supported.

webcpp::asio::browser::transport::non_blocking

Reports the default transport result without accessing a network.

Synopses

Reports the default transport result without accessing a network.

[[nodiscard]]
bool
non_blocking() const noexcept;

Reports the default transport result without accessing a network.

boost::system::error_code
non_blocking(bool);

Return Value

  • False.

  • operation_not_supported.

webcpp::asio::browser::transport::non_blocking

Reports the default transport result without accessing a network.

Synopsis

[[nodiscard]]
bool
non_blocking() const noexcept;

Return Value

False.

Note

The return value should not be discarded.

webcpp::asio::browser::transport::non_blocking

Reports the default transport result without accessing a network.

Synopsis

boost::system::error_code
non_blocking(bool);

Return Value

operation_not_supported.

webcpp::asio::browser::transport::read_some

Reports the default transport result without accessing a network.

Synopsis

template<class MutableBufferSequence>
std::size_t
read_some(
    MutableBufferSequence const&,
    boost::system::error_code& ec);

Return Value

Zero.

Template Parameters

Name Description

MutableBufferSequence

The operation argument type.

Parameters

Name Description

ec

Receives operation_not_supported.

webcpp::asio::browser::transport::receive

Reports the default transport result without accessing a network.

Synopsis

template<class MutableBufferSequence>
std::size_t
receive(
    MutableBufferSequence const&,
    webcpp::asio_backend::socket_base::message_flags,
    boost::system::error_code& ec);

Return Value

Zero.

Template Parameters

Name Description

MutableBufferSequence

The operation argument type.

Parameters

Name Description

ec

Receives operation_not_supported.

webcpp::asio::browser::transport::receive_from

Reports the default transport result without accessing a network.

Synopsis

template<class MutableBufferSequence>
std::size_t
receive_from(
    MutableBufferSequence const&,
    endpoint_type&,
    webcpp::asio_backend::socket_base::message_flags,
    boost::system::error_code& ec);

Return Value

Zero.

Template Parameters

Name Description

MutableBufferSequence

The operation argument type.

Parameters

Name Description

ec

Receives operation_not_supported.

webcpp::asio::browser::transport::remote_endpoint

Reports the default transport result without accessing a network.

Synopsis

endpoint_type
remote_endpoint(boost::system::error_code& ec) const;

Return Value

An unspecified endpoint.

Parameters

Name Description

ec

Receives operation_not_supported.

webcpp::asio::browser::transport::send

Reports the default transport result without accessing a network.

Synopsis

template<class ConstBufferSequence>
std::size_t
send(
    ConstBufferSequence const&,
    webcpp::asio_backend::socket_base::message_flags,
    boost::system::error_code& ec);

Return Value

Zero.

Template Parameters

Name Description

ConstBufferSequence

The operation argument type.

Parameters

Name Description

ec

Receives operation_not_supported.

webcpp::asio::browser::transport::send_to

Reports the default transport result without accessing a network.

Synopsis

template<class ConstBufferSequence>
std::size_t
send_to(
    ConstBufferSequence const&,
    endpoint_type const&,
    webcpp::asio_backend::socket_base::message_flags,
    boost::system::error_code& ec);

Return Value

Zero.

Template Parameters

Name Description

ConstBufferSequence

The operation argument type.

Parameters

Name Description

ec

Receives operation_not_supported.

webcpp::asio::browser::transport::set_option

Reports the default transport result without accessing a network.

Synopsis

template<class SettableSocketOption>
boost::system::error_code
set_option(SettableSocketOption const&);

Return Value

operation_not_supported.

Template Parameters

Name Description

SettableSocketOption

The operation argument type.

webcpp::asio::browser::transport::shutdown

Reports the default transport result without accessing a network.

Synopsis

boost::system::error_code
shutdown(webcpp::asio_backend::socket_base::shutdown_type);

Return Value

operation_not_supported.

webcpp::asio::browser::transport::write_some

Reports the default transport result without accessing a network.

Synopsis

template<class ConstBufferSequence>
std::size_t
write_some(
    ConstBufferSequence const&,
    boost::system::error_code& ec);

Return Value

Zero.

Template Parameters

Name Description

ConstBufferSequence

The operation argument type.

Parameters

Name Description

ec

Receives operation_not_supported.

webcpp::asio::browser::async_await

Asynchronously receives a JavaScript Promise’s value or rejection reason.

Synopsis

template<
    class CompletionToken,
    class Executor = webcpp::asio_backend::any_io_executor>
auto
async_await(
    Executor const& executor,
    emscripten::val promise,
    CompletionToken&& token);

Description

Completion is posted through the bridge, never invoked inline. Terminal, partial or total cancellation posts operation_aborted and undefined; it does not cancel the JavaScript Promise. A pending wait owns outstanding work. Destroying its context destroys its handler without calling it. Operation storage uses the handler’s associated allocator.

Return Value

The result determined by token.

Template Parameters

Name Description

Executor

The concrete or type-erased executor of the owning context.

CompletionToken

A token for void(boost::system::error_code, emscripten::val).

Parameters

Name Description

executor

The executor whose context owns the wait.

promise

A Promise or a value normalized by JavaScript Promise.resolve.

token

The completion token.

See Also

"Promises and events", in the guide.

webcpp::asio::browser::async_wait_event

Asynchronously receives the next event of type on a JavaScript EventTarget.

Synopsis

template<
    class CompletionToken,
    class Executor = webcpp::asio_backend::any_io_executor>
auto
async_wait_event(
    Executor const& executor,
    emscripten::val target,
    std::string_view type,
    CompletionToken&& token);

Description

Completion is posted through the bridge. Terminal, partial or total cancellation removes the listener and posts operation_aborted and undefined. A pending wait owns outstanding work. Context destruction removes the listener and destroys its handler silently. The event type is copied even when initiation is deferred.

Return Value

The result determined by token.

Template Parameters

Name Description

Executor

The concrete or type-erased executor of the owning context.

CompletionToken

A token for void(boost::system::error_code, emscripten::val).

Parameters

Name Description

executor

The executor whose context owns the wait.

target

The JavaScript EventTarget.

type

The event type, which need not end in a null byte.

token

The completion token.

See Also

"Await one browser event", in the guide.

webcpp::asio::browser::operator==

Compares the contexts owning two executors.

Synopsis

constexpr
bool
operator==(
    executor_type const&,
    executor_type const&) = default;
Note

This function is a hidden friend of executor_type, declared only inside that class: it can be found only through argument-dependent lookup.

Return Value

True when the executors belong to the same context.

webcpp::asio::ip

Types

Name Description

basic_resolver

Preserves a host and service for browser transports without querying DNS.

tcp

The browser TCP protocol, with operations supplied by a transport.

udp

The browser UDP protocol, with operations supplied by a transport.

Functions

Name Description

operator&

operator&=

operator^

operator^=

operator|

operator|=

operator~

operator==

Compares address families.

webcpp::asio::ip::basic_resolver

Preserves a host and service for browser transports without querying DNS.

Synopsis

template<
    class InternetProtocol,
    class Executor = webcpp::asio_backend::any_io_executor>
class basic_resolver
    : public webcpp::asio_backend::ip::resolver_base

Base Classes

Name Description

webcpp::asio_backend::ip::resolver_base

Type Aliases

Name Description

endpoint_type

The protocol endpoint type.

executor_type

The associated executor type.

protocol_type

The internet protocol type.

results_type

Boost’s sequence of resolver entries.

Member Functions

Name Description

basic_resolver [constructor]

Constructors

async_resolve

async_resolve overloads

cancel

Leaves already-computed, posted results unchanged.

get_executor

Returns the associated executor.

resolve

resolve overloads

Non-Member Functions

Template Parameters

Name Description

InternetProtocol

The internet protocol.

Executor

The associated executor.

See Also

"Sockets and transports", in the guide.

webcpp::asio::ip::basic_resolver::endpoint_type

The protocol endpoint type.

Synopsis

using endpoint_type = InternetProtocol::endpoint;

webcpp::asio::ip::basic_resolver::executor_type

The associated executor type.

Synopsis

using executor_type = Executor;

webcpp::asio::ip::basic_resolver::protocol_type

The internet protocol type.

Synopsis

using protocol_type = InternetProtocol;

webcpp::asio::ip::basic_resolver::results_type

Boost’s sequence of resolver entries.

Synopsis

using results_type = webcpp::asio_backend::ip::basic_resolver_results<InternetProtocol>;

webcpp::asio::ip::basic_resolver::basic_resolver

Constructors

Synopses

Constructs a resolver on executor.

explicit
basic_resolver(executor_type executor);

Constructs a resolver on context.

template<class ExecutionContext>
requires std::is_convertible_v<ExecutionContext&,
                                       ::webcpp::asio_backend::execution_context&>
explicit
basic_resolver(ExecutionContext& context);

Template Parameters

Name Description

ExecutionContext

An execution context type.

Parameters

Name Description

executor

The completion executor.

context

The context that runs completions.

webcpp::asio::ip::basic_resolver::basic_resolver

Constructs a resolver on executor.

Synopsis

explicit
basic_resolver(executor_type executor);

Parameters

Name Description

executor

The completion executor.

webcpp::asio::ip::basic_resolver::basic_resolver

Constructs a resolver on context.

Synopsis

template<class ExecutionContext>
requires std::is_convertible_v<ExecutionContext&,
                                       ::webcpp::asio_backend::execution_context&>
explicit
basic_resolver(ExecutionContext& context);

Template Parameters

Name Description

ExecutionContext

An execution context type.

Parameters

Name Description

context

The context that runs completions.

webcpp::asio::ip::basic_resolver::async_resolve

async_resolve overloads

Synopses

Posts operation_not_supported for reverse resolution.

template<class ResolveToken>
auto
async_resolve(
    endpoint_type const& endpoint,
    ResolveToken&& token);

Posts a forward resolution result.

template<class ResolveToken>
auto
async_resolve(
    std::string_view host,
    std::string_view service,
    ResolveToken&& token);

Posts a forward result with service parsing flags.

template<class ResolveToken>
auto
async_resolve(
    std::string_view host,
    std::string_view service,
    flags resolve_flags,
    ResolveToken&& token);

Return Value

The token result for void(error_code, results_type).

Template Parameters

Name Description

ResolveToken

The completion token type.

Parameters

Name Description

endpoint

The endpoint.

token

The completion token.

host

The original host, copied before returning.

service

The original service, copied before returning.

resolve_flags

The service parsing flags.

webcpp::asio::ip::basic_resolver::async_resolve

Posts operation_not_supported for reverse resolution.

Synopsis

template<class ResolveToken>
auto
async_resolve(
    endpoint_type const& endpoint,
    ResolveToken&& token);

Return Value

The token result for void(error_code, results_type).

Template Parameters

Name Description

ResolveToken

The completion token type.

Parameters

Name Description

endpoint

The endpoint.

token

The completion token.

webcpp::asio::ip::basic_resolver::async_resolve

Posts a forward resolution result.

Synopsis

template<class ResolveToken>
auto
async_resolve(
    std::string_view host,
    std::string_view service,
    ResolveToken&& token);

Return Value

The token result for void(error_code, results_type).

Template Parameters

Name Description

ResolveToken

The completion token type.

Parameters

Name Description

host

The original host, copied before returning.

service

The original service, copied before returning.

token

The completion token.

webcpp::asio::ip::basic_resolver::async_resolve

Posts a forward result with service parsing flags.

Synopsis

template<class ResolveToken>
auto
async_resolve(
    std::string_view host,
    std::string_view service,
    flags resolve_flags,
    ResolveToken&& token);

Description

Copies the inputs with the token’s associated allocator before returning. Deferred tokens retain those copies and compute the result only when initiated. Bind an allocator to the deferred token to select its input storage allocator.

Return Value

The token result for void(error_code, results_type).

Template Parameters

Name Description

ResolveToken

The completion token type.

Parameters

Name Description

host

The original host, copied before returning.

service

The original service, copied before returning.

resolve_flags

The service parsing flags.

token

The completion token.

webcpp::asio::ip::basic_resolver::cancel

Leaves already-computed, posted results unchanged.

Synopsis

void
cancel();

webcpp::asio::ip::basic_resolver::get_executor

Returns the associated executor.

Synopsis

[[nodiscard]]
executor_type
get_executor() const noexcept;

Return Value

The executor.

Note

The return value should not be discarded.

webcpp::asio::ip::basic_resolver::resolve

resolve overloads

Synopses

Refuses reverse resolution by throwing operation_not_supported.

results_type
resolve(endpoint_type const& endpoint);

Constructs a forward result, throwing on an unsupported service.

results_type
resolve(
    std::string_view host,
    std::string_view service);

Refuses reverse resolution without accessing DNS.

results_type
resolve(
    endpoint_type const&,
    boost::system::error_code& ec);

Constructs a forward result with flags, throwing on an unsupported service.

results_type
resolve(
    std::string_view host,
    std::string_view service,
    flags resolve_flags);

Constructs an entry retaining host and service, with an unspecified address.

results_type
resolve(
    std::string_view host,
    std::string_view service,
    boost::system::error_code& ec);

Constructs a forward result under the service parsing flags.

results_type
resolve(
    std::string_view host,
    std::string_view service,
    flags resolve_flags,
    boost::system::error_code& ec);

Return Value

  • An empty sequence if the exception hook returns.

  • One resolver entry.

  • An empty sequence.

  • One entry on success, otherwise an empty sequence.

Parameters

Name Description

endpoint

The endpoint.

host

The original host.

service

The original service.

ec

Receives operation_not_supported.

resolve_flags

The service parsing flags.

webcpp::asio::ip::basic_resolver::resolve

Refuses reverse resolution by throwing operation_not_supported.

Synopsis

results_type
resolve(endpoint_type const& endpoint);

Return Value

An empty sequence if the exception hook returns.

Parameters

Name Description

endpoint

The endpoint.

webcpp::asio::ip::basic_resolver::resolve

Constructs a forward result, throwing on an unsupported service.

Synopsis

results_type
resolve(
    std::string_view host,
    std::string_view service);

Return Value

One resolver entry.

Parameters

Name Description

host

The original host.

service

The original service.

webcpp::asio::ip::basic_resolver::resolve

Refuses reverse resolution without accessing DNS.

Synopsis

results_type
resolve(
    endpoint_type const&,
    boost::system::error_code& ec);

Return Value

An empty sequence.

Parameters

Name Description

ec

Receives operation_not_supported.

webcpp::asio::ip::basic_resolver::resolve

Constructs a forward result with flags, throwing on an unsupported service.

Synopsis

results_type
resolve(
    std::string_view host,
    std::string_view service,
    flags resolve_flags);

Return Value

One resolver entry.

Parameters

Name Description

host

The original host.

service

The original service.

resolve_flags

The service parsing flags.

webcpp::asio::ip::basic_resolver::resolve

Constructs an entry retaining host and service, with an unspecified address.

Synopsis

results_type
resolve(
    std::string_view host,
    std::string_view service,
    boost::system::error_code& ec);

Return Value

One entry on success, otherwise an empty sequence.

Parameters

Name Description

host

The host name retained verbatim.

service

An empty, numeric or supported named service.

ec

Receives success or service_not_found.

webcpp::asio::ip::basic_resolver::resolve

Constructs a forward result under the service parsing flags.

Synopsis

results_type
resolve(
    std::string_view host,
    std::string_view service,
    flags resolve_flags,
    boost::system::error_code& ec);

Return Value

One entry on success, otherwise an empty sequence.

Parameters

Name Description

host

The host name retained verbatim.

service

The service retained verbatim.

resolve_flags

Only numeric_service affects parsing.

ec

Receives success or service_not_found.

webcpp::asio::ip::tcp

The browser TCP protocol, with operations supplied by a transport.

Synopsis

Declared in <webcpp/asio/ip/tcp.hpp>

class tcp;

Type Aliases

Name Description

acceptor

The acceptor type.

endpoint

The endpoint type.

resolver

The resolver type.

socket

The socket type.

Member Functions

Name Description

family

Returns the address family.

protocol

Returns the protocol number.

type

Returns the socket type constant.

Static Member Functions

Name Description

v4

Returns the IPv4 protocol.

v6

Returns the IPv6 protocol.

Friends

Name Description

webcpp::asio::ip::operator==

Compares address families.

webcpp::asio::ip::tcp::acceptor

The acceptor type.

Synopsis

Declared in <webcpp/asio/ip/tcp.hpp>

using acceptor = basic_socket_acceptor<tcp>;

webcpp::asio::ip::tcp::endpoint

The endpoint type.

Synopsis

Declared in <webcpp/asio/ip/tcp.hpp>

using endpoint = webcpp::asio_backend::ip::basic_endpoint<tcp>;

webcpp::asio::ip::tcp::resolver

The resolver type.

Synopsis

Declared in <webcpp/asio/ip/tcp.hpp>

using resolver = basic_resolver<tcp>;

webcpp::asio::ip::tcp::socket

The socket type.

Synopsis

Declared in <webcpp/asio/ip/tcp.hpp>

using socket = basic_stream_socket<tcp>;

webcpp::asio::ip::tcp::family

Returns the address family.

Synopsis

Declared in <webcpp/asio/ip/tcp.hpp>

[[nodiscard]]
int
family() const noexcept;

Return Value

The address family.

Note

The return value should not be discarded.

webcpp::asio::ip::tcp::protocol

Returns the protocol number.

Synopsis

Declared in <webcpp/asio/ip/tcp.hpp>

[[nodiscard]]
int
protocol() const noexcept;

Return Value

The protocol number.

Note

The return value should not be discarded.

webcpp::asio::ip::tcp::type

Returns the socket type constant.

Synopsis

Declared in <webcpp/asio/ip/tcp.hpp>

[[nodiscard]]
int
type() const noexcept;

Return Value

The socket type.

Note

The return value should not be discarded.

webcpp::asio::ip::tcp::v4

Returns the IPv4 protocol.

Synopsis

Declared in <webcpp/asio/ip/tcp.hpp>

static
tcp
v4() noexcept;

Return Value

The IPv4 protocol.

webcpp::asio::ip::tcp::v6

Returns the IPv6 protocol.

Synopsis

Declared in <webcpp/asio/ip/tcp.hpp>

static
tcp
v6() noexcept;

Return Value

The IPv6 protocol.

webcpp::asio::ip::udp

The browser UDP protocol, with operations supplied by a transport.

Synopsis

Declared in <webcpp/asio/ip/udp.hpp>

class udp;

Type Aliases

Name Description

endpoint

The endpoint type.

resolver

The resolver type.

socket

The socket type.

Member Functions

Name Description

family

Returns the address family.

protocol

Returns the protocol number.

type

Returns the socket type constant.

Static Member Functions

Name Description

v4

Returns the IPv4 protocol.

v6

Returns the IPv6 protocol.

Friends

Name Description

webcpp::asio::ip::operator==

Compares address families.

webcpp::asio::ip::udp::endpoint

The endpoint type.

Synopsis

Declared in <webcpp/asio/ip/udp.hpp>

using endpoint = webcpp::asio_backend::ip::basic_endpoint<udp>;

webcpp::asio::ip::udp::resolver

The resolver type.

Synopsis

Declared in <webcpp/asio/ip/udp.hpp>

using resolver = basic_resolver<udp>;

webcpp::asio::ip::udp::socket

The socket type.

Synopsis

Declared in <webcpp/asio/ip/udp.hpp>

using socket = basic_datagram_socket<udp>;

webcpp::asio::ip::udp::family

Returns the address family.

Synopsis

Declared in <webcpp/asio/ip/udp.hpp>

[[nodiscard]]
int
family() const noexcept;

Return Value

The address family.

Note

The return value should not be discarded.

webcpp::asio::ip::udp::protocol

Returns the protocol number.

Synopsis

Declared in <webcpp/asio/ip/udp.hpp>

[[nodiscard]]
int
protocol() const noexcept;

Return Value

The protocol number.

Note

The return value should not be discarded.

webcpp::asio::ip::udp::type

Returns the socket type constant.

Synopsis

Declared in <webcpp/asio/ip/udp.hpp>

[[nodiscard]]
int
type() const noexcept;

Return Value

The socket type.

Note

The return value should not be discarded.

webcpp::asio::ip::udp::v4

Returns the IPv4 protocol.

Synopsis

Declared in <webcpp/asio/ip/udp.hpp>

static
udp
v4() noexcept;

Return Value

The IPv4 protocol.

webcpp::asio::ip::udp::v6

Returns the IPv6 protocol.

Synopsis

Declared in <webcpp/asio/ip/udp.hpp>

static
udp
v6() noexcept;

Return Value

The IPv6 protocol.

webcpp::asio::ip::operator&

Synopsis

flags
operator&(
    flags x,
    flags y);
Note

This function is a hidden friend of basic_resolver, declared inside its base class resolver_base: it can be found only through argument-dependent lookup.

webcpp::asio::ip::operator&=

Synopsis

flags&
operator&=(
    flags& x,
    flags y);
Note

This function is a hidden friend of basic_resolver, declared inside its base class resolver_base: it can be found only through argument-dependent lookup.

webcpp::asio::ip::operator^

Synopsis

flags
operator^(
    flags x,
    flags y);
Note

This function is a hidden friend of basic_resolver, declared inside its base class resolver_base: it can be found only through argument-dependent lookup.

webcpp::asio::ip::operator^=

Synopsis

flags&
operator^=(
    flags& x,
    flags y);
Note

This function is a hidden friend of basic_resolver, declared inside its base class resolver_base: it can be found only through argument-dependent lookup.

webcpp::asio::ip::operator|

Synopsis

flags
operator|(
    flags x,
    flags y);
Note

This function is a hidden friend of basic_resolver, declared inside its base class resolver_base: it can be found only through argument-dependent lookup.

webcpp::asio::ip::operator|=

Synopsis

flags&
operator|=(
    flags& x,
    flags y);
Note

This function is a hidden friend of basic_resolver, declared inside its base class resolver_base: it can be found only through argument-dependent lookup.

webcpp::asio::ip::operator~

Synopsis

flags
operator~(flags x);
Note

This function is a hidden friend of basic_resolver, declared inside its base class resolver_base: it can be found only through argument-dependent lookup.

webcpp::asio::ip::operator==

Compares address families.

Synopses

Declared in <webcpp/asio/ip/tcp.hpp>

Compares address families.

constexpr
bool
operator==(
    tcp const& a,
    tcp const& b) noexcept = default;

Compares address families.

constexpr
bool
operator==(
    udp const& a,
    udp const& b) noexcept = default;

Return Value

Whether they match.

Parameters

Name Description

a

The first protocol.

b

The second protocol.

webcpp::asio::ip::operator==

Compares address families.

Synopsis

Declared in <webcpp/asio/ip/tcp.hpp>

constexpr
bool
operator==(
    tcp const& a,
    tcp const& b) noexcept = default;
Note

This function is a hidden friend of tcp, declared only inside that class: it can be found only through argument-dependent lookup.

Return Value

Whether they match.

Parameters

Name Description

a

The first protocol.

b

The second protocol.

webcpp::asio::ip::operator==

Compares address families.

Synopsis

Declared in <webcpp/asio/ip/udp.hpp>

constexpr
bool
operator==(
    udp const& a,
    udp const& b) noexcept = default;
Note

This function is a hidden friend of udp, declared only inside that class: it can be found only through argument-dependent lookup.

Return Value

Whether they match.

Parameters

Name Description

a

The first protocol.

b

The second protocol.

webcpp::asio::ssl

Types

Name Description

context

Records TLS settings without implementing TLS or reading certificate files.

context_base

Names the TLS methods and option values compatible with Boost and OpenSSL 3.

host_name_verification

Owns the host name requested for certificate verification.

stream_base

Names the handshake roles for browser stream adapters.

Type Aliases

Name Description

verify_mode

The peer verification bitmask type.

Enums

Name Description

verify_callback_kind

Identifies the recorded verification callback without executing it.

Variables

Name Description

verify_client_once

Requests a client certificate only once.

verify_fail_if_no_peer_cert

Requires a peer certificate when peer verification is requested.

verify_none

Requests no peer verification.

verify_peer

Requests peer verification.

webcpp::asio::ssl::verify_mode

The peer verification bitmask type.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

using verify_mode = int;

webcpp::asio::ssl::context

Records TLS settings without implementing TLS or reading certificate files.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

class context
    : public context_base

Description

Browser stream adapters decide which settings their transport can honor.

Base Classes

Name Description

context_base

Names the TLS methods and option values compatible with Boost and OpenSSL 3.

Member Functions

Name Description

context [constructor]

Constructors

~context [destructor]

Releases the recorded host storage.

operator=

Assignment operators

add_certificate_authority

Records a request to add certificate roots.

add_verify_path

Records a root-directory request without accessing it.

client_credentials

Returns the recorded setting.

default_verify_paths

Returns the recorded setting.

load_verify_file

Records a root-file request without accessing the file.

recorded_callback

Returns the recorded setting.

recorded_method

Returns the recorded setting.

recorded_options

Returns the recorded setting.

recorded_verify_mode

Returns the recorded setting.

roots_added

Returns the recorded setting.

set_default_verify_paths

set_default_verify_paths overloads

set_options

Adds requested TLS option bits.

set_verify_callback

set_verify_callback overloads

set_verify_mode

Records the requested verification mode.

use_certificate

Records a client certificate request.

use_certificate_chain

Records a client certificate chain request.

use_certificate_chain_file

Records a chain-file request without accessing it.

use_certificate_file

Records a certificate-file request without accessing it.

use_private_key

Records a client private key request.

use_private_key_file

Records a private-key-file request without accessing it.

verification_host

Returns the recorded setting.

See Also

"Explanation: TLS settings", in the guide.

webcpp::asio::ssl::context::context

Constructors

Synopses

Declared in <webcpp/asio/ssl.hpp>

A context cannot be copied.

context(context const&) = delete;

Transfers the record and its host storage.

constexpr
context(context&& other) noexcept = default;

Constructs an empty record using the default memory resource.

explicit
context(method selected);

Constructs a record whose verification host uses resource.

context(
    method selected,
    std::pmr::memory_resource* resource);

Parameters

Name Description

other

The source record.

selected

The requested TLS method.

resource

The host storage resource, or null for the default resource.

webcpp::asio::ssl::context::context

A context cannot be copied.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

context(context const&) = delete;

webcpp::asio::ssl::context::context

Transfers the record and its host storage.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

constexpr
context(context&& other) noexcept = default;

Parameters

Name Description

other

The source record.

webcpp::asio::ssl::context::context

Constructs an empty record using the default memory resource.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

explicit
context(method selected);

Parameters

Name Description

selected

The requested TLS method.

webcpp::asio::ssl::context::context

Constructs a record whose verification host uses resource.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

context(
    method selected,
    std::pmr::memory_resource* resource);

Parameters

Name Description

selected

The requested TLS method.

resource

The host storage resource, or null for the default resource.

webcpp::asio::ssl::context::~context

Releases the recorded host storage.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

constexpr
~context() = default;

webcpp::asio::ssl::context::operator=

Assignment operators

Synopses

Declared in <webcpp/asio/ssl.hpp>

A context cannot be copy-assigned.

context&
operator=(context const&) = delete;

Moves the record, retaining the destination’s memory resource.

context&
operator=(context&& other) noexcept(/* see-below */) = default;

Return Value

This record.

Parameters

Name Description

other

The source record.

webcpp::asio::ssl::context::operator=

A context cannot be copy-assigned.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

context&
operator=(context const&) = delete;

webcpp::asio::ssl::context::operator=

Moves the record, retaining the destination’s memory resource.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

context&
operator=(context&& other) noexcept(/* see-below */) = default;

Exception specification

This function is potentially-throwing unless std::is_nothrow_move_assignable_v<std::pmr::string>.

Return Value

This record.

Parameters

Name Description

other

The source record.

webcpp::asio::ssl::context::add_certificate_authority

Records a request to add certificate roots.

Synopses

Declared in <webcpp/asio/ssl.hpp>

Records a request to add certificate roots.

void
add_certificate_authority(webcpp::asio_backend::const_buffer const& ca);

Records a request to add certificate roots.

void
add_certificate_authority(
    webcpp::asio_backend::const_buffer const& ca,
    boost::system::error_code& ec);

Parameters

Name Description

ca

The certificate authority data.

ec

Receives success.

webcpp::asio::ssl::context::add_certificate_authority

Records a request to add certificate roots.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
add_certificate_authority(webcpp::asio_backend::const_buffer const& ca);

Parameters

Name Description

ca

The certificate authority data.

webcpp::asio::ssl::context::add_certificate_authority

Records a request to add certificate roots.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
add_certificate_authority(
    webcpp::asio_backend::const_buffer const& ca,
    boost::system::error_code& ec);

Parameters

Name Description

ca

The certificate authority data.

ec

Receives success.

webcpp::asio::ssl::context::add_verify_path

Records a root-directory request without accessing it.

Synopses

Declared in <webcpp/asio/ssl.hpp>

Records a root-directory request without accessing it.

void
add_verify_path(std::string_view path);

Records a root-directory request without accessing it.

void
add_verify_path(
    std::string_view path,
    boost::system::error_code& ec);

Parameters

Name Description

path

The requested root certificate directory.

ec

Receives success.

webcpp::asio::ssl::context::add_verify_path

Records a root-directory request without accessing it.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
add_verify_path(std::string_view path);

Parameters

Name Description

path

The requested root certificate directory.

webcpp::asio::ssl::context::add_verify_path

Records a root-directory request without accessing it.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
add_verify_path(
    std::string_view path,
    boost::system::error_code& ec);

Parameters

Name Description

path

The requested root certificate directory.

ec

Receives success.

webcpp::asio::ssl::context::client_credentials

Returns the recorded setting.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

[[nodiscard]]
bool
client_credentials() const noexcept;

Return Value

Whether client credentials were requested.

Note

The return value should not be discarded.

webcpp::asio::ssl::context::default_verify_paths

Returns the recorded setting.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

[[nodiscard]]
bool
default_verify_paths() const noexcept;

Return Value

Whether default verification paths were requested.

Note

The return value should not be discarded.

webcpp::asio::ssl::context::load_verify_file

Records a root-file request without accessing the file.

Synopses

Declared in <webcpp/asio/ssl.hpp>

Records a root-file request without accessing the file.

void
load_verify_file(std::string_view filename);

Records a root-file request without accessing the file.

void
load_verify_file(
    std::string_view filename,
    boost::system::error_code& ec);

Parameters

Name Description

filename

The requested root certificate file.

ec

Receives success.

webcpp::asio::ssl::context::load_verify_file

Records a root-file request without accessing the file.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
load_verify_file(std::string_view filename);

Parameters

Name Description

filename

The requested root certificate file.

webcpp::asio::ssl::context::load_verify_file

Records a root-file request without accessing the file.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
load_verify_file(
    std::string_view filename,
    boost::system::error_code& ec);

Parameters

Name Description

filename

The requested root certificate file.

ec

Receives success.

webcpp::asio::ssl::context::recorded_callback

Returns the recorded setting.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

[[nodiscard]]
verify_callback_kind
recorded_callback() const noexcept;

Return Value

The verification callback kind.

Note

The return value should not be discarded.

webcpp::asio::ssl::context::recorded_method

Returns the recorded setting.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

[[nodiscard]]
method
recorded_method() const noexcept;

Return Value

The requested TLS method.

Note

The return value should not be discarded.

webcpp::asio::ssl::context::recorded_options

Returns the recorded setting.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

[[nodiscard]]
options
recorded_options() const noexcept;

Return Value

The accumulated TLS option bits.

Note

The return value should not be discarded.

webcpp::asio::ssl::context::recorded_verify_mode

Returns the recorded setting.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

[[nodiscard]]
verify_mode
recorded_verify_mode() const noexcept;

Return Value

The requested verification mode.

Note

The return value should not be discarded.

webcpp::asio::ssl::context::roots_added

Returns the recorded setting.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

[[nodiscard]]
bool
roots_added() const noexcept;

Return Value

Whether additional certificate roots were requested.

Note

The return value should not be discarded.

webcpp::asio::ssl::context::set_default_verify_paths

set_default_verify_paths overloads

Synopses

Declared in <webcpp/asio/ssl.hpp>

Records a request for default verification paths.

Records a request for default verification paths.

void
set_default_verify_paths(boost::system::error_code& ec);

Parameters

Name Description

ec

Receives success.

webcpp::asio::ssl::context::set_default_verify_paths

Records a request for default verification paths.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
set_default_verify_paths();

webcpp::asio::ssl::context::set_default_verify_paths

Records a request for default verification paths.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
set_default_verify_paths(boost::system::error_code& ec);

Parameters

Name Description

ec

Receives success.

webcpp::asio::ssl::context::set_options

Adds requested TLS option bits.

Synopses

Declared in <webcpp/asio/ssl.hpp>

Adds requested TLS option bits.

void
set_options(options value);

Adds requested TLS option bits.

void
set_options(
    options value,
    boost::system::error_code& ec);

Parameters

Name Description

value

The option bits to add.

ec

Receives success.

webcpp::asio::ssl::context::set_options

Adds requested TLS option bits.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
set_options(options value);

Parameters

Name Description

value

The option bits to add.

webcpp::asio::ssl::context::set_options

Adds requested TLS option bits.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
set_options(
    options value,
    boost::system::error_code& ec);

Parameters

Name Description

value

The option bits to add.

ec

Receives success.

webcpp::asio::ssl::context::set_verify_callback

set_verify_callback overloads

Synopses

Declared in <webcpp/asio/ssl.hpp>

Records the verification callback without an error-code argument.

template<class VerifyCallback>
void
set_verify_callback(VerifyCallback const& callback);

Records the verification callback kind and, for host verification, its name.

template<class VerifyCallback>
void
set_verify_callback(
    VerifyCallback const& callback,
    boost::system::error_code& ec);

Template Parameters

Name Description

VerifyCallback

The callback type.

Parameters

Name Description

callback

The verification request.

ec

Receives success.

webcpp::asio::ssl::context::set_verify_callback

Records the verification callback without an error-code argument.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

template<class VerifyCallback>
void
set_verify_callback(VerifyCallback const& callback);

Template Parameters

Name Description

VerifyCallback

The callback type.

Parameters

Name Description

callback

The verification request.

webcpp::asio::ssl::context::set_verify_callback

Records the verification callback kind and, for host verification, its name.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

template<class VerifyCallback>
void
set_verify_callback(
    VerifyCallback const& callback,
    boost::system::error_code& ec);

Template Parameters

Name Description

VerifyCallback

The callback type.

Parameters

Name Description

callback

The verification request; it is never invoked here.

ec

Receives success.

webcpp::asio::ssl::context::set_verify_mode

Records the requested verification mode.

Synopses

Declared in <webcpp/asio/ssl.hpp>

Records the requested verification mode.

Records the requested verification mode.

void
set_verify_mode(
    verify_mode mode,
    boost::system::error_code& ec);

Parameters

Name Description

mode

The requested verification bitmask.

ec

Receives success.

webcpp::asio::ssl::context::set_verify_mode

Records the requested verification mode.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
set_verify_mode(verify_mode mode);

Parameters

Name Description

mode

The requested verification bitmask.

webcpp::asio::ssl::context::set_verify_mode

Records the requested verification mode.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
set_verify_mode(
    verify_mode mode,
    boost::system::error_code& ec);

Parameters

Name Description

mode

The requested verification bitmask.

ec

Receives success.

webcpp::asio::ssl::context::use_certificate

Records a client certificate request.

Synopses

Declared in <webcpp/asio/ssl.hpp>

Records a client certificate request.

void
use_certificate(
    webcpp::asio_backend::const_buffer const& certificate,
    file_format format);

Records a client certificate request.

void
use_certificate(
    webcpp::asio_backend::const_buffer const& certificate,
    file_format format,
    boost::system::error_code& ec);

Parameters

Name Description

certificate

The certificate bytes.

format

The certificate encoding.

ec

Receives success.

webcpp::asio::ssl::context::use_certificate

Records a client certificate request.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
use_certificate(
    webcpp::asio_backend::const_buffer const& certificate,
    file_format format);

Parameters

Name Description

certificate

The certificate bytes.

format

The certificate encoding.

webcpp::asio::ssl::context::use_certificate

Records a client certificate request.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
use_certificate(
    webcpp::asio_backend::const_buffer const& certificate,
    file_format format,
    boost::system::error_code& ec);

Parameters

Name Description

certificate

The certificate bytes.

format

The certificate encoding.

ec

Receives success.

webcpp::asio::ssl::context::use_certificate_chain

Records a client certificate chain request.

Synopses

Declared in <webcpp/asio/ssl.hpp>

Records a client certificate chain request.

void
use_certificate_chain(webcpp::asio_backend::const_buffer const& chain);

Records a client certificate chain request.

void
use_certificate_chain(
    webcpp::asio_backend::const_buffer const& chain,
    boost::system::error_code& ec);

Parameters

Name Description

chain

The certificate chain bytes.

ec

Receives success.

webcpp::asio::ssl::context::use_certificate_chain

Records a client certificate chain request.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
use_certificate_chain(webcpp::asio_backend::const_buffer const& chain);

Parameters

Name Description

chain

The certificate chain bytes.

webcpp::asio::ssl::context::use_certificate_chain

Records a client certificate chain request.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
use_certificate_chain(
    webcpp::asio_backend::const_buffer const& chain,
    boost::system::error_code& ec);

Parameters

Name Description

chain

The certificate chain bytes.

ec

Receives success.

webcpp::asio::ssl::context::use_certificate_chain_file

Records a chain-file request without accessing it.

Synopses

Declared in <webcpp/asio/ssl.hpp>

Records a chain-file request without accessing it.

void
use_certificate_chain_file(std::string_view filename);

Records a chain-file request without accessing it.

void
use_certificate_chain_file(
    std::string_view filename,
    boost::system::error_code& ec);

Parameters

Name Description

filename

The requested chain file.

ec

Receives success.

webcpp::asio::ssl::context::use_certificate_chain_file

Records a chain-file request without accessing it.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
use_certificate_chain_file(std::string_view filename);

Parameters

Name Description

filename

The requested chain file.

webcpp::asio::ssl::context::use_certificate_chain_file

Records a chain-file request without accessing it.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
use_certificate_chain_file(
    std::string_view filename,
    boost::system::error_code& ec);

Parameters

Name Description

filename

The requested chain file.

ec

Receives success.

webcpp::asio::ssl::context::use_certificate_file

Records a certificate-file request without accessing it.

Synopses

Declared in <webcpp/asio/ssl.hpp>

Records a certificate-file request without accessing it.

void
use_certificate_file(
    std::string_view filename,
    file_format format);

Records a certificate-file request without accessing it.

void
use_certificate_file(
    std::string_view filename,
    file_format format,
    boost::system::error_code& ec);

Parameters

Name Description

filename

The requested certificate file.

format

The certificate encoding.

ec

Receives success.

webcpp::asio::ssl::context::use_certificate_file

Records a certificate-file request without accessing it.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
use_certificate_file(
    std::string_view filename,
    file_format format);

Parameters

Name Description

filename

The requested certificate file.

format

The certificate encoding.

webcpp::asio::ssl::context::use_certificate_file

Records a certificate-file request without accessing it.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
use_certificate_file(
    std::string_view filename,
    file_format format,
    boost::system::error_code& ec);

Parameters

Name Description

filename

The requested certificate file.

format

The certificate encoding.

ec

Receives success.

webcpp::asio::ssl::context::use_private_key

Records a client private key request.

Synopses

Declared in <webcpp/asio/ssl.hpp>

Records a client private key request.

void
use_private_key(
    webcpp::asio_backend::const_buffer const& key,
    file_format format);

Records a client private key request.

void
use_private_key(
    webcpp::asio_backend::const_buffer const& key,
    file_format format,
    boost::system::error_code& ec);

Parameters

Name Description

key

The private key bytes.

format

The key encoding.

ec

Receives success.

webcpp::asio::ssl::context::use_private_key

Records a client private key request.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
use_private_key(
    webcpp::asio_backend::const_buffer const& key,
    file_format format);

Parameters

Name Description

key

The private key bytes.

format

The key encoding.

webcpp::asio::ssl::context::use_private_key

Records a client private key request.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
use_private_key(
    webcpp::asio_backend::const_buffer const& key,
    file_format format,
    boost::system::error_code& ec);

Parameters

Name Description

key

The private key bytes.

format

The key encoding.

ec

Receives success.

webcpp::asio::ssl::context::use_private_key_file

Records a private-key-file request without accessing it.

Synopses

Declared in <webcpp/asio/ssl.hpp>

Records a private-key-file request without accessing it.

void
use_private_key_file(
    std::string_view filename,
    file_format format);

Records a private-key-file request without accessing it.

void
use_private_key_file(
    std::string_view filename,
    file_format format,
    boost::system::error_code& ec);

Parameters

Name Description

filename

The requested key file.

format

The key encoding.

ec

Receives success.

webcpp::asio::ssl::context::use_private_key_file

Records a private-key-file request without accessing it.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
use_private_key_file(
    std::string_view filename,
    file_format format);

Parameters

Name Description

filename

The requested key file.

format

The key encoding.

webcpp::asio::ssl::context::use_private_key_file

Records a private-key-file request without accessing it.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

void
use_private_key_file(
    std::string_view filename,
    file_format format,
    boost::system::error_code& ec);

Parameters

Name Description

filename

The requested key file.

format

The key encoding.

ec

Receives success.

webcpp::asio::ssl::context::verification_host

Returns the recorded setting.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

[[nodiscard]]
std::string_view
verification_host() const noexcept;

Return Value

The recorded verification host.

Note

The return value should not be discarded.

webcpp::asio::ssl::context_base

Names the TLS methods and option values compatible with Boost and OpenSSL 3.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

class context_base;

Type Aliases

Name Description

options

The TLS option bitmask type.

verify_mode

The legacy context-level verification bitmask alias.

Enums

Name Description

file_format

The certificate or key representation.

method

The TLS method names in Boost’s enumeration order.

Static Data Members

Name Description

default_workarounds

Requests the OpenSSL 3 compatibility workaround bits.

no_compression

Requests disabling compression.

no_sslv2

Retains the OpenSSL 3 legacy SSLv2 disabling option.

no_sslv3

Requests disabling SSLv3.

no_tlsv1

Requests disabling TLSv1.

no_tlsv1_1

Requests disabling TLSv1.1.

no_tlsv1_2

Requests disabling TLSv1.2.

no_tlsv1_3

Requests disabling TLSv1.3.

single_dh_use

Retains the OpenSSL 3 legacy single-use DH option.

verify_client_once

The legacy context-level verify_client_once value.

verify_fail_if_no_peer_cert

The legacy context-level verify_fail_if_no_peer_cert value.

verify_none

The legacy context-level verify_none value.

verify_peer

The legacy context-level verify_peer value.

Protected Member Functions

Name Description

~context_base [destructor]

Prevents deletion through the constants-only base.

Derived Classes

Name Description

context

Records TLS settings without implementing TLS or reading certificate files.

webcpp::asio::ssl::context_base::options

The TLS option bitmask type.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

using options = uint64_t;

webcpp::asio::ssl::context_base::verify_mode

The legacy context-level verification bitmask alias.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

using verify_mode = ssl::verify_mode;

webcpp::asio::ssl::context_base::file_format

The certificate or key representation.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

enum file_format;

Members

Name Description

asn1

ASN.1 encoding.

pem

PEM encoding.

webcpp::asio::ssl::context_base::method

The TLS method names in Boost’s enumeration order.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

enum method;

Members

Name Description

sslv2

The sslv2 generic method.

sslv2_client

The sslv2 client method.

sslv2_server

The sslv2 server method.

sslv3

The sslv3 generic method.

sslv3_client

The sslv3 client method.

sslv3_server

The sslv3 server method.

tlsv1

The tlsv1 generic method.

tlsv1_client

The tlsv1 client method.

tlsv1_server

The tlsv1 server method.

sslv23

The sslv23 generic method.

sslv23_client

The sslv23 client method.

sslv23_server

The sslv23 server method.

tlsv11

The tlsv11 generic method.

tlsv11_client

The tlsv11 client method.

tlsv11_server

The tlsv11 server method.

tlsv12

The tlsv12 generic method.

tlsv12_client

The tlsv12 client method.

tlsv12_server

The tlsv12 server method.

tlsv13

The tlsv13 generic method.

tlsv13_client

The tlsv13 client method.

tlsv13_server

The tlsv13 server method.

tls

The tls generic method.

tls_client

The tls client method.

tls_server

The tls server method.

webcpp::asio::ssl::context_base::default_workarounds

Requests the OpenSSL 3 compatibility workaround bits.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr static
options default_workarounds = 0x80000850ULL;

webcpp::asio::ssl::context_base::no_compression

Requests disabling compression.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr static
options no_compression = 0x00020000ULL;

webcpp::asio::ssl::context_base::no_sslv2

Retains the OpenSSL 3 legacy SSLv2 disabling option.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr static
options no_sslv2 = 0;

webcpp::asio::ssl::context_base::no_sslv3

Requests disabling SSLv3.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr static
options no_sslv3 = 0x02000000ULL;

webcpp::asio::ssl::context_base::no_tlsv1

Requests disabling TLSv1.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr static
options no_tlsv1 = 0x04000000ULL;

webcpp::asio::ssl::context_base::no_tlsv1_1

Requests disabling TLSv1.1.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr static
options no_tlsv1_1 = 0x10000000ULL;

webcpp::asio::ssl::context_base::no_tlsv1_2

Requests disabling TLSv1.2.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr static
options no_tlsv1_2 = 0x08000000ULL;

webcpp::asio::ssl::context_base::no_tlsv1_3

Requests disabling TLSv1.3.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr static
options no_tlsv1_3 = 0x20000000ULL;

webcpp::asio::ssl::context_base::single_dh_use

Retains the OpenSSL 3 legacy single-use DH option.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr static
options single_dh_use = 0;

webcpp::asio::ssl::context_base::verify_client_once

The legacy context-level verify_client_once value.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr static
verify_mode verify_client_once = ssl::verify_client_once;

webcpp::asio::ssl::context_base::verify_fail_if_no_peer_cert

The legacy context-level verify_fail_if_no_peer_cert value.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr static
verify_mode verify_fail_if_no_peer_cert = ssl::verify_fail_if_no_peer_cert;

webcpp::asio::ssl::context_base::verify_none

The legacy context-level verify_none value.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr static
verify_mode verify_none = ssl::verify_none;

webcpp::asio::ssl::context_base::verify_peer

The legacy context-level verify_peer value.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr static
verify_mode verify_peer = ssl::verify_peer;

webcpp::asio::ssl::context_base::~context_base

Prevents deletion through the constants-only base.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

constexpr
~context_base() = default;

webcpp::asio::ssl::host_name_verification

Owns the host name requested for certificate verification.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

class host_name_verification;

Member Functions

Name Description

host_name_verification [constructor]

Copies the verification host so temporary input storage is safe.

host

Returns the owned host name as a view.

webcpp::asio::ssl::host_name_verification::host_name_verification

Copies the verification host so temporary input storage is safe.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

explicit
host_name_verification(std::string_view host);

Parameters

Name Description

host

The expected host name.

webcpp::asio::ssl::host_name_verification::host

Returns the owned host name as a view.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

[[nodiscard]]
std::string_view
host() const noexcept;

Return Value

A view valid until this object changes or is destroyed.

Note

The return value should not be discarded.

webcpp::asio::ssl::stream_base

Names the handshake roles for browser stream adapters.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

class stream_base;

Enums

Name Description

handshake_type

Which endpoint starts the handshake.

Protected Member Functions

Name Description

~stream_base [destructor]

Prevents deletion through the constants-only base.

webcpp::asio::ssl::stream_base::handshake_type

Which endpoint starts the handshake.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

enum handshake_type;

Members

Name Description

client

The client role.

server

The server role.

webcpp::asio::ssl::stream_base::~stream_base

Prevents deletion through the constants-only base.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

constexpr
~stream_base() = default;

webcpp::asio::ssl::verify_callback_kind

Identifies the recorded verification callback without executing it.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

enum class verify_callback_kind : uint8_t;

Members

Name Description

none

No callback was supplied.

host_name_verification

A host-name verification request.

other

Any other verification callback.

webcpp::asio::ssl::verify_client_once

Requests a client certificate only once.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr verify_mode verify_client_once = 0x04;

webcpp::asio::ssl::verify_fail_if_no_peer_cert

Requires a peer certificate when peer verification is requested.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr verify_mode verify_fail_if_no_peer_cert = 0x02;

webcpp::asio::ssl::verify_none

Requests no peer verification.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr verify_mode verify_none = 0x00;

webcpp::asio::ssl::verify_peer

Requests peer verification.

Synopsis

Declared in <webcpp/asio/ssl.hpp>

inline constexpr verify_mode verify_peer = 0x01;

webcpp::asio::wasi

Types

Name Description

stdio_stream

A WASIp2 CLI AsyncReadStream and AsyncWriteStream driven by pollables.

Functions

Name Description

beast_close_socket

Cancels the channel for Beast timeouts.

webcpp::asio::wasi::stdio_stream

A WASIp2 CLI AsyncReadStream and AsyncWriteStream driven by pollables.

Synopsis

class stdio_stream;

Description

Owns resource handles, without closing libc’s stdin/stdout descriptors. Only one read and one write may be outstanding at once. Operations retain buffers until completion and preserve allocator, executor and cancellation associations. Host imports may still block according to the host’s behavior.

Type Aliases

Name Description

executor_type

The executor used for readiness.

lowest_layer_type

This stream is its own lowest layer.

Member Functions

Name Description

stdio_stream [constructor]

Constructors

~stdio_stream [destructor]

Cancels pending operations and releases resources after their completion.

operator=

Assignment operators

async_read_some

Reads a partial sequence asynchronously.

async_write_some

Writes a partial sequence asynchronously.

cancel

Cancels outstanding operations; subsequent operations remain usable.

close

Cancels outstanding operations and disables subsequent operations.

get_executor

Returns the readiness executor.

lowest_layer

Returns this stream.

read_some

read_some overloads

write_some

write_some overloads

See Also

"Build for WASIp2", in the guide.

webcpp::asio::wasi::stdio_stream::executor_type

The executor used for readiness.

Synopsis

using executor_type = webcpp::asio_backend::io_context::executor_type;

webcpp::asio::wasi::stdio_stream::lowest_layer_type

This stream is its own lowest layer.

Synopsis

using lowest_layer_type = stdio_stream;

webcpp::asio::wasi::stdio_stream::stdio_stream

Constructors

Synopses

Forbids copied resource ownership.

stdio_stream(stdio_stream const&) = delete;

Transfers resource ownership.

Acquires CLI resources using the executor’s context allocator.

explicit
stdio_stream(executor_type const& executor);

Parameters

Name Description

executor

Drives asynchronous readiness.

webcpp::asio::wasi::stdio_stream::stdio_stream

Forbids copied resource ownership.

Synopsis

stdio_stream(stdio_stream const&) = delete;

webcpp::asio::wasi::stdio_stream::stdio_stream

Transfers resource ownership.

Synopsis

stdio_stream(stdio_stream&&);

webcpp::asio::wasi::stdio_stream::stdio_stream

Acquires CLI resources using the executor’s context allocator.

Synopsis

explicit
stdio_stream(executor_type const& executor);

Parameters

Name Description

executor

Drives asynchronous readiness.

webcpp::asio::wasi::stdio_stream::~stdio_stream

Cancels pending operations and releases resources after their completion.

Synopsis

~stdio_stream();

webcpp::asio::wasi::stdio_stream::operator=

Assignment operators

Synopses

Forbids copied resource ownership.

stdio_stream&
operator=(stdio_stream const&) = delete;

Forbids replacing a stream that may have pending operations.

webcpp::asio::wasi::stdio_stream::operator=

Forbids copied resource ownership.

Synopsis

stdio_stream&
operator=(stdio_stream const&) = delete;

webcpp::asio::wasi::stdio_stream::operator=

Forbids replacing a stream that may have pending operations.

Synopsis

stdio_stream&
operator=(stdio_stream&&) = delete;

webcpp::asio::wasi::stdio_stream::async_read_some

Reads a partial sequence asynchronously.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_read_some(
    Buffers const& buffers,
    Token&& token);

Return Value

The completion token’s result.

Template Parameters

Name Description

Buffers

Mutable buffer sequence.

Token

Completion token for void(error_code, size_t).

Parameters

Name Description

buffers

Destination storage, alive until completion.

token

Receives the error and byte count.

webcpp::asio::wasi::stdio_stream::async_write_some

Writes a partial sequence asynchronously.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_write_some(
    Buffers const& buffers,
    Token&& token);

Return Value

The completion token’s result.

Template Parameters

Name Description

Buffers

Const buffer sequence.

Token

Completion token for void(error_code, size_t).

Parameters

Name Description

buffers

Source storage, alive until completion.

token

Receives the error and byte count.

webcpp::asio::wasi::stdio_stream::cancel

Cancels outstanding operations; subsequent operations remain usable.

Synopsis

void
cancel();

webcpp::asio::wasi::stdio_stream::close

Cancels outstanding operations and disables subsequent operations.

Synopsis

void
close();

webcpp::asio::wasi::stdio_stream::get_executor

Returns the readiness executor.

Synopsis

[[nodiscard]]
executor_type
get_executor() const noexcept;

Return Value

The executor.

Note

The return value should not be discarded.

webcpp::asio::wasi::stdio_stream::lowest_layer

Returns this stream.

Synopsis

lowest_layer_type&
lowest_layer() noexcept;

Return Value

This stream.

webcpp::asio::wasi::stdio_stream::read_some

read_some overloads

Synopses

Reads synchronously and throws on failure.

template<class Buffers>
std::size_t
read_some(Buffers const& buffers);

Reads synchronously.

template<class Buffers>
std::size_t
read_some(
    Buffers const& buffers,
    boost::system::error_code& error);

Return Value

Bytes read.

Template Parameters

Name Description

Buffers

Mutable buffer sequence.

Parameters

Name Description

buffers

Destination bytes.

error

Receives failure.

webcpp::asio::wasi::stdio_stream::read_some

Reads synchronously and throws on failure.

Synopsis

template<class Buffers>
std::size_t
read_some(Buffers const& buffers);

Return Value

Bytes read.

Template Parameters

Name Description

Buffers

Mutable buffer sequence.

Parameters

Name Description

buffers

Destination bytes.

webcpp::asio::wasi::stdio_stream::read_some

Reads synchronously.

Synopsis

template<class Buffers>
std::size_t
read_some(
    Buffers const& buffers,
    boost::system::error_code& error);

Return Value

Bytes read.

Template Parameters

Name Description

Buffers

Mutable buffer sequence.

Parameters

Name Description

buffers

Destination bytes.

error

Receives failure.

webcpp::asio::wasi::stdio_stream::write_some

write_some overloads

Synopses

Writes synchronously and throws on failure.

template<class Buffers>
std::size_t
write_some(Buffers const& buffers);

Writes synchronously.

template<class Buffers>
std::size_t
write_some(
    Buffers const& buffers,
    boost::system::error_code& error);

Return Value

Bytes written.

Template Parameters

Name Description

Buffers

Const buffer sequence.

Parameters

Name Description

buffers

Source bytes.

error

Receives failure.

webcpp::asio::wasi::stdio_stream::write_some

Writes synchronously and throws on failure.

Synopsis

template<class Buffers>
std::size_t
write_some(Buffers const& buffers);

Return Value

Bytes written.

Template Parameters

Name Description

Buffers

Const buffer sequence.

Parameters

Name Description

buffers

Source bytes.

webcpp::asio::wasi::stdio_stream::write_some

Writes synchronously.

Synopsis

template<class Buffers>
std::size_t
write_some(
    Buffers const& buffers,
    boost::system::error_code& error);

Return Value

Bytes written.

Template Parameters

Name Description

Buffers

Const buffer sequence.

Parameters

Name Description

buffers

Source bytes.

error

Receives failure.

webcpp::asio::wasi::beast_close_socket

Cancels the channel for Beast timeouts.

Synopsis

void
beast_close_socket(stdio_stream& stream);

Parameters

Name Description

stream

Channel to close.

webcpp::asio::basic_waitable_timer

Boost.Asio’s timer on Clock, Boost’s own: on emscripten it waits in the reactor’s timer queue, which the run family waits on.

Synopsis

template<
    class Clock,
    class WaitTraits = webcpp::asio_backend::wait_traits<Clock>,
    class Executor = webcpp::asio_backend::any_io_executor>
using basic_waitable_timer = webcpp::asio_backend::basic_waitable_timer<Clock, WaitTraits, Executor>;

Template Parameters

Name Description

Clock

A clock of std::chrono’s, or one that meets the same requirements.

WaitTraits

How a time on Clock becomes the duration the timer waits for.

Executor

The executor the timer’s operations run on.

webcpp::asio::basic_datagram_socket

A browser datagram socket whose operations use browser::transport.

Synopsis

template<
    class Protocol,
    class Executor = webcpp::asio_backend::any_io_executor>
class basic_datagram_socket;

Type Aliases

Name Description

endpoint_type

The endpoint type.

executor_type

The executor type.

protocol_type

The protocol type.

Member Functions

Name Description

async_connect

Initiates connect and posts its completion.

async_receive

async_receive overloads

async_receive_from

async_receive_from overloads

async_send

async_send overloads

async_send_to

async_send_to overloads

connect

connect overloads

receive

receive overloads

receive_from

receive_from overloads

send

send overloads

send_to

send_to overloads

shutdown

shutdown overloads

Using Declarations

Name Description

Unnamed using

Inherits executor, context, protocol and endpoint constructors.

Template Parameters

Name Description

Protocol

The network protocol.

Executor

The associated executor.

webcpp::asio::basic_datagram_socket::endpoint_type

The endpoint type.

Synopsis

using endpoint_type = Protocol::endpoint;

webcpp::asio::basic_datagram_socket::executor_type

The executor type.

Synopsis

using executor_type = Executor;

webcpp::asio::basic_datagram_socket::protocol_type

The protocol type.

Synopsis

using protocol_type = Protocol;

webcpp::asio::basic_datagram_socket::async_connect

Initiates connect and posts its completion.

Synopsis

template<class Token>
auto
async_connect(
    endpoint_type const& endpoint,
    Token&& token);

Return Value

The completion token result.

Template Parameters

Name Description

Token

The completion token type.

Parameters

Name Description

endpoint

The endpoint.

token

The completion token.

webcpp::asio::basic_datagram_socket::async_receive

async_receive overloads

Synopses

Initiates receive with no message flags.

template<
    class Buffers,
    class Token>
auto
async_receive(
    Buffers const& buffers,
    Token&& token);

Initiates receive and posts its completion.

template<
    class Buffers,
    class Token>
auto
async_receive(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    Token&& token);

Return Value

  • The token result.

  • The completion token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

token

The completion token.

flags

The flags.

webcpp::asio::basic_datagram_socket::async_receive

Initiates receive with no message flags.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_receive(
    Buffers const& buffers,
    Token&& token);

Return Value

The token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

token

The completion token.

webcpp::asio::basic_datagram_socket::async_receive

Initiates receive and posts its completion.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_receive(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    Token&& token);

Return Value

The completion token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

token

The completion token.

webcpp::asio::basic_datagram_socket::async_receive_from

async_receive_from overloads

Synopses

Initiates receive_from with no message flags.

template<
    class Buffers,
    class Token>
auto
async_receive_from(
    Buffers const& buffers,
    endpoint_type& endpoint,
    Token&& token);

Initiates receive_from and posts its completion.

template<
    class Buffers,
    class Token>
auto
async_receive_from(
    Buffers const& buffers,
    endpoint_type& endpoint,
    webcpp::asio_backend::socket_base::message_flags flags,
    Token&& token);

Return Value

  • The token result.

  • The completion token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

token

The completion token.

flags

The flags.

webcpp::asio::basic_datagram_socket::async_receive_from

Initiates receive_from with no message flags.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_receive_from(
    Buffers const& buffers,
    endpoint_type& endpoint,
    Token&& token);

Return Value

The token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

token

The completion token.

webcpp::asio::basic_datagram_socket::async_receive_from

Initiates receive_from and posts its completion.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_receive_from(
    Buffers const& buffers,
    endpoint_type& endpoint,
    webcpp::asio_backend::socket_base::message_flags flags,
    Token&& token);

Return Value

The completion token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

flags

The flags.

token

The completion token.

webcpp::asio::basic_datagram_socket::async_send

async_send overloads

Synopses

Initiates send with no message flags.

template<
    class Buffers,
    class Token>
auto
async_send(
    Buffers const& buffers,
    Token&& token);

Initiates send and posts its completion.

template<
    class Buffers,
    class Token>
auto
async_send(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    Token&& token);

Return Value

  • The token result.

  • The completion token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

token

The completion token.

flags

The flags.

webcpp::asio::basic_datagram_socket::async_send

Initiates send with no message flags.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_send(
    Buffers const& buffers,
    Token&& token);

Return Value

The token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

token

The completion token.

webcpp::asio::basic_datagram_socket::async_send

Initiates send and posts its completion.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_send(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    Token&& token);

Return Value

The completion token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

token

The completion token.

webcpp::asio::basic_datagram_socket::async_send_to

async_send_to overloads

Synopses

Initiates send_to with no message flags.

template<
    class Buffers,
    class Token>
auto
async_send_to(
    Buffers const& buffers,
    endpoint_type const& endpoint,
    Token&& token);

Initiates send_to and posts its completion.

template<
    class Buffers,
    class Token>
auto
async_send_to(
    Buffers const& buffers,
    endpoint_type const& endpoint,
    webcpp::asio_backend::socket_base::message_flags flags,
    Token&& token);

Return Value

  • The token result.

  • The completion token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

token

The completion token.

flags

The flags.

webcpp::asio::basic_datagram_socket::async_send_to

Initiates send_to with no message flags.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_send_to(
    Buffers const& buffers,
    endpoint_type const& endpoint,
    Token&& token);

Return Value

The token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

token

The completion token.

webcpp::asio::basic_datagram_socket::async_send_to

Initiates send_to and posts its completion.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_send_to(
    Buffers const& buffers,
    endpoint_type const& endpoint,
    webcpp::asio_backend::socket_base::message_flags flags,
    Token&& token);

Return Value

The completion token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

flags

The flags.

token

The completion token.

webcpp::asio::basic_datagram_socket::connect

connect overloads

Synopses

Forwards connect, throwing on error.

void
connect(endpoint_type const& endpoint);

Forwards connect to the transport.

boost::system::error_code
connect(
    endpoint_type const& endpoint,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Parameters

Name Description

endpoint

The endpoint.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::connect

Forwards connect, throwing on error.

Synopsis

void
connect(endpoint_type const& endpoint);

Parameters

Name Description

endpoint

The endpoint.

webcpp::asio::basic_datagram_socket::connect

Forwards connect to the transport.

Synopsis

boost::system::error_code
connect(
    endpoint_type const& endpoint,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Parameters

Name Description

endpoint

The endpoint.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::receive

receive overloads

Synopses

Uses receive with no message flags.

template<class Buffers>
std::size_t
receive(Buffers const& buffers);

Forwards receive, throwing on error.

template<class Buffers>
std::size_t
receive(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags);

Uses receive with no message flags.

template<class Buffers>
std::size_t
receive(
    Buffers const& buffers,
    boost::system::error_code& ec);

Forwards receive to the transport.

template<class Buffers>
std::size_t
receive(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    boost::system::error_code& ec);

Return Value

  • The byte count.

  • The operation result.

  • The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::receive

Uses receive with no message flags.

Synopsis

template<class Buffers>
std::size_t
receive(Buffers const& buffers);

Return Value

The byte count.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

webcpp::asio::basic_datagram_socket::receive

Forwards receive, throwing on error.

Synopsis

template<class Buffers>
std::size_t
receive(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags);

Return Value

The operation result.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

webcpp::asio::basic_datagram_socket::receive

Uses receive with no message flags.

Synopsis

template<class Buffers>
std::size_t
receive(
    Buffers const& buffers,
    boost::system::error_code& ec);

Return Value

The byte count.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::receive

Forwards receive to the transport.

Synopsis

template<class Buffers>
std::size_t
receive(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::receive_from

receive_from overloads

Synopses

Uses receive_from with no message flags.

template<class Buffers>
std::size_t
receive_from(
    Buffers const& buffers,
    endpoint_type& endpoint);

Forwards receive_from, throwing on error.

template<class Buffers>
std::size_t
receive_from(
    Buffers const& buffers,
    endpoint_type& endpoint,
    webcpp::asio_backend::socket_base::message_flags flags);

Uses receive_from with no message flags.

template<class Buffers>
std::size_t
receive_from(
    Buffers const& buffers,
    endpoint_type& endpoint,
    boost::system::error_code& ec);

Forwards receive_from to the transport.

template<class Buffers>
std::size_t
receive_from(
    Buffers const& buffers,
    endpoint_type& endpoint,
    webcpp::asio_backend::socket_base::message_flags flags,
    boost::system::error_code& ec);

Return Value

  • The byte count.

  • The operation result.

  • The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

flags

The flags.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::receive_from

Uses receive_from with no message flags.

Synopsis

template<class Buffers>
std::size_t
receive_from(
    Buffers const& buffers,
    endpoint_type& endpoint);

Return Value

The byte count.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

webcpp::asio::basic_datagram_socket::receive_from

Forwards receive_from, throwing on error.

Synopsis

template<class Buffers>
std::size_t
receive_from(
    Buffers const& buffers,
    endpoint_type& endpoint,
    webcpp::asio_backend::socket_base::message_flags flags);

Return Value

The operation result.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

flags

The flags.

webcpp::asio::basic_datagram_socket::receive_from

Uses receive_from with no message flags.

Synopsis

template<class Buffers>
std::size_t
receive_from(
    Buffers const& buffers,
    endpoint_type& endpoint,
    boost::system::error_code& ec);

Return Value

The byte count.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::receive_from

Forwards receive_from to the transport.

Synopsis

template<class Buffers>
std::size_t
receive_from(
    Buffers const& buffers,
    endpoint_type& endpoint,
    webcpp::asio_backend::socket_base::message_flags flags,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

flags

The flags.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::send

send overloads

Synopses

Uses send with no message flags.

template<class Buffers>
std::size_t
send(Buffers const& buffers);

Forwards send, throwing on error.

template<class Buffers>
std::size_t
send(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags);

Uses send with no message flags.

template<class Buffers>
std::size_t
send(
    Buffers const& buffers,
    boost::system::error_code& ec);

Forwards send to the transport.

template<class Buffers>
std::size_t
send(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    boost::system::error_code& ec);

Return Value

  • The byte count.

  • The operation result.

  • The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::send

Uses send with no message flags.

Synopsis

template<class Buffers>
std::size_t
send(Buffers const& buffers);

Return Value

The byte count.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

webcpp::asio::basic_datagram_socket::send

Forwards send, throwing on error.

Synopsis

template<class Buffers>
std::size_t
send(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags);

Return Value

The operation result.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

webcpp::asio::basic_datagram_socket::send

Uses send with no message flags.

Synopsis

template<class Buffers>
std::size_t
send(
    Buffers const& buffers,
    boost::system::error_code& ec);

Return Value

The byte count.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::send

Forwards send to the transport.

Synopsis

template<class Buffers>
std::size_t
send(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::send_to

send_to overloads

Synopses

Uses send_to with no message flags.

template<class Buffers>
std::size_t
send_to(
    Buffers const& buffers,
    endpoint_type const& endpoint);

Forwards send_to, throwing on error.

template<class Buffers>
std::size_t
send_to(
    Buffers const& buffers,
    endpoint_type const& endpoint,
    webcpp::asio_backend::socket_base::message_flags flags);

Uses send_to with no message flags.

template<class Buffers>
std::size_t
send_to(
    Buffers const& buffers,
    endpoint_type const& endpoint,
    boost::system::error_code& ec);

Forwards send_to to the transport.

template<class Buffers>
std::size_t
send_to(
    Buffers const& buffers,
    endpoint_type const& endpoint,
    webcpp::asio_backend::socket_base::message_flags flags,
    boost::system::error_code& ec);

Return Value

  • The byte count.

  • The operation result.

  • The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

flags

The flags.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::send_to

Uses send_to with no message flags.

Synopsis

template<class Buffers>
std::size_t
send_to(
    Buffers const& buffers,
    endpoint_type const& endpoint);

Return Value

The byte count.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

webcpp::asio::basic_datagram_socket::send_to

Forwards send_to, throwing on error.

Synopsis

template<class Buffers>
std::size_t
send_to(
    Buffers const& buffers,
    endpoint_type const& endpoint,
    webcpp::asio_backend::socket_base::message_flags flags);

Return Value

The operation result.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

flags

The flags.

webcpp::asio::basic_datagram_socket::send_to

Uses send_to with no message flags.

Synopsis

template<class Buffers>
std::size_t
send_to(
    Buffers const& buffers,
    endpoint_type const& endpoint,
    boost::system::error_code& ec);

Return Value

The byte count.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::send_to

Forwards send_to to the transport.

Synopsis

template<class Buffers>
std::size_t
send_to(
    Buffers const& buffers,
    endpoint_type const& endpoint,
    webcpp::asio_backend::socket_base::message_flags flags,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

endpoint

The endpoint.

flags

The flags.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::shutdown

shutdown overloads

Synopses

Forwards shutdown, throwing on error.

void
shutdown(webcpp::asio_backend::socket_base::shutdown_type what);

Forwards shutdown to the transport.

boost::system::error_code
shutdown(
    webcpp::asio_backend::socket_base::shutdown_type what,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Parameters

Name Description

what

The what.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::shutdown

Forwards shutdown, throwing on error.

Synopsis

void
shutdown(webcpp::asio_backend::socket_base::shutdown_type what);

Parameters

Name Description

what

The what.

webcpp::asio::basic_datagram_socket::shutdown

Forwards shutdown to the transport.

Synopsis

boost::system::error_code
shutdown(
    webcpp::asio_backend::socket_base::shutdown_type what,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Parameters

Name Description

what

The what.

ec

Receives the transport error, or success.

webcpp::asio::basic_datagram_socket::Unnamed using

Inherits executor, context, protocol and endpoint constructors.

Synopsis

using base::;

webcpp::asio::basic_socket_acceptor

A browser socket acceptor whose operations use browser::transport.

Synopsis

template<
    class Protocol,
    class Executor = webcpp::asio_backend::any_io_executor>
class basic_socket_acceptor;

Type Aliases

Name Description

endpoint_type

The endpoint type.

executor_type

The executor type.

protocol_type

The protocol type.

socket_type

The accepted socket type.

Member Functions

Name Description

accept

accept overloads

async_accept

async_accept overloads

listen

listen overloads

Using Declarations

Name Description

Unnamed using

Inherits executor, context, protocol and endpoint constructors.

Template Parameters

Name Description

Protocol

The network protocol.

Executor

The associated executor.

webcpp::asio::basic_socket_acceptor::endpoint_type

The endpoint type.

Synopsis

using endpoint_type = Protocol::endpoint;

webcpp::asio::basic_socket_acceptor::executor_type

The executor type.

Synopsis

using executor_type = Executor;

webcpp::asio::basic_socket_acceptor::protocol_type

The protocol type.

Synopsis

using protocol_type = Protocol;

webcpp::asio::basic_socket_acceptor::socket_type

The accepted socket type.

webcpp::asio::basic_socket_acceptor::accept

accept overloads

Synopses

Returns an accepted socket, throwing on error.

Returns a socket with the acceptance result.

socket_type
accept(boost::system::error_code& ec);

Forwards accept, throwing on error.

void
accept(socket_type& peer);

Forwards accept to the transport.

boost::system::error_code
accept(
    socket_type& peer,
    boost::system::error_code& ec);

Return Value

  • The accepted socket.

  • The accepted socket, or a closed socket on failure.

  • The result; ec receives any error.

Parameters

Name Description

ec

Receives the transport error, or success.

peer

The peer socket or remote endpoint.

webcpp::asio::basic_socket_acceptor::accept

Returns an accepted socket, throwing on error.

Synopsis

socket_type
accept();

Return Value

The accepted socket.

webcpp::asio::basic_socket_acceptor::accept

Returns a socket with the acceptance result.

Synopsis

socket_type
accept(boost::system::error_code& ec);

Return Value

The accepted socket, or a closed socket on failure.

Parameters

Name Description

ec

Receives the transport error, or success.

webcpp::asio::basic_socket_acceptor::accept

Forwards accept, throwing on error.

Synopsis

void
accept(socket_type& peer);

Parameters

Name Description

peer

The peer socket or remote endpoint.

webcpp::asio::basic_socket_acceptor::accept

Forwards accept to the transport.

Synopsis

boost::system::error_code
accept(
    socket_type& peer,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Parameters

Name Description

peer

The peer socket or remote endpoint.

ec

Receives the transport error, or success.

webcpp::asio::basic_socket_acceptor::async_accept

async_accept overloads

Synopses

Accepts a socket whose storage stays stable until completion.

template<class Token>
auto
async_accept(Token&& token);

Accepts into peer asynchronously.

template<class Token>
auto
async_accept(
    socket_type& peer,
    Token&& token);

Return Value

The token result.

Template Parameters

Name Description

Token

The completion token type.

Parameters

Name Description

token

The completion token.

peer

The peer socket or remote endpoint.

webcpp::asio::basic_socket_acceptor::async_accept

Accepts a socket whose storage stays stable until completion.

Synopsis

template<class Token>
auto
async_accept(Token&& token);

Return Value

The token result.

Template Parameters

Name Description

Token

The completion token type.

Parameters

Name Description

token

The completion token.

webcpp::asio::basic_socket_acceptor::async_accept

Accepts into peer asynchronously.

Synopsis

template<class Token>
auto
async_accept(
    socket_type& peer,
    Token&& token);

Return Value

The token result.

Template Parameters

Name Description

Token

The completion token type.

Parameters

Name Description

peer

The peer socket or remote endpoint.

token

The completion token.

webcpp::asio::basic_socket_acceptor::listen

listen overloads

Synopses

Listens with the default backlog, throwing on error.

void
listen();

Forwards listen, throwing on error.

void
listen(int backlog);

Listens with the default backlog.

boost::system::error_code
listen(boost::system::error_code& ec);

Forwards listen to the transport.

boost::system::error_code
listen(
    int backlog,
    boost::system::error_code& ec);

Return Value

  • The error code.

  • The result; ec receives any error.

Parameters

Name Description

backlog

The backlog.

ec

Receives the transport error, or success.

webcpp::asio::basic_socket_acceptor::listen

Listens with the default backlog, throwing on error.

Synopsis

void
listen();

webcpp::asio::basic_socket_acceptor::listen

Forwards listen, throwing on error.

Synopsis

void
listen(int backlog);

Parameters

Name Description

backlog

The backlog.

webcpp::asio::basic_socket_acceptor::listen

Listens with the default backlog.

Synopsis

boost::system::error_code
listen(boost::system::error_code& ec);

Return Value

The error code.

Parameters

Name Description

ec

Receives the transport error, or success.

webcpp::asio::basic_socket_acceptor::listen

Forwards listen to the transport.

Synopsis

boost::system::error_code
listen(
    int backlog,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Parameters

Name Description

backlog

The backlog.

ec

Receives the transport error, or success.

webcpp::asio::basic_socket_acceptor::Unnamed using

Inherits executor, context, protocol and endpoint constructors.

Synopsis

using base::;

webcpp::asio::basic_stream_socket

A browser stream socket whose operations use browser::transport.

Synopsis

template<
    class Protocol,
    class Executor = webcpp::asio_backend::any_io_executor>
class basic_stream_socket;

Type Aliases

Name Description

endpoint_type

The endpoint type.

executor_type

The executor type.

protocol_type

The protocol type.

Member Functions

Name Description

async_connect

Initiates connect and posts its completion.

async_read_some

Initiates read_some and posts its completion.

async_receive

async_receive overloads

async_send

async_send overloads

async_write_some

Initiates write_some and posts its completion.

connect

connect overloads

read_some

read_some overloads

receive

receive overloads

send

send overloads

shutdown

shutdown overloads

write_some

write_some overloads

Using Declarations

Name Description

Unnamed using

Inherits executor, context, protocol and endpoint constructors.

Template Parameters

Name Description

Protocol

The network protocol.

Executor

The associated executor.

webcpp::asio::basic_stream_socket::endpoint_type

The endpoint type.

Synopsis

using endpoint_type = Protocol::endpoint;

webcpp::asio::basic_stream_socket::executor_type

The executor type.

Synopsis

using executor_type = Executor;

webcpp::asio::basic_stream_socket::protocol_type

The protocol type.

Synopsis

using protocol_type = Protocol;

webcpp::asio::basic_stream_socket::async_connect

Initiates connect and posts its completion.

Synopsis

template<class Token>
auto
async_connect(
    endpoint_type const& endpoint,
    Token&& token);

Return Value

The completion token result.

Template Parameters

Name Description

Token

The completion token type.

Parameters

Name Description

endpoint

The endpoint.

token

The completion token.

webcpp::asio::basic_stream_socket::async_read_some

Initiates read_some and posts its completion.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_read_some(
    Buffers const& buffers,
    Token&& token);

Return Value

The completion token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

token

The completion token.

webcpp::asio::basic_stream_socket::async_receive

async_receive overloads

Synopses

Initiates receive with no message flags.

template<
    class Buffers,
    class Token>
auto
async_receive(
    Buffers const& buffers,
    Token&& token);

Initiates receive and posts its completion.

template<
    class Buffers,
    class Token>
auto
async_receive(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    Token&& token);

Return Value

  • The token result.

  • The completion token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

token

The completion token.

flags

The flags.

webcpp::asio::basic_stream_socket::async_receive

Initiates receive with no message flags.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_receive(
    Buffers const& buffers,
    Token&& token);

Return Value

The token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

token

The completion token.

webcpp::asio::basic_stream_socket::async_receive

Initiates receive and posts its completion.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_receive(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    Token&& token);

Return Value

The completion token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

token

The completion token.

webcpp::asio::basic_stream_socket::async_send

async_send overloads

Synopses

Initiates send with no message flags.

template<
    class Buffers,
    class Token>
auto
async_send(
    Buffers const& buffers,
    Token&& token);

Initiates send and posts its completion.

template<
    class Buffers,
    class Token>
auto
async_send(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    Token&& token);

Return Value

  • The token result.

  • The completion token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

token

The completion token.

flags

The flags.

webcpp::asio::basic_stream_socket::async_send

Initiates send with no message flags.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_send(
    Buffers const& buffers,
    Token&& token);

Return Value

The token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

token

The completion token.

webcpp::asio::basic_stream_socket::async_send

Initiates send and posts its completion.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_send(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    Token&& token);

Return Value

The completion token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

token

The completion token.

webcpp::asio::basic_stream_socket::async_write_some

Initiates write_some and posts its completion.

Synopsis

template<
    class Buffers,
    class Token>
auto
async_write_some(
    Buffers const& buffers,
    Token&& token);

Return Value

The completion token result.

Template Parameters

Name Description

Buffers

The operation type.

Token

The completion token type.

Parameters

Name Description

buffers

The buffers.

token

The completion token.

webcpp::asio::basic_stream_socket::connect

connect overloads

Synopses

Forwards connect, throwing on error.

void
connect(endpoint_type const& endpoint);

Forwards connect to the transport.

boost::system::error_code
connect(
    endpoint_type const& endpoint,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Parameters

Name Description

endpoint

The endpoint.

ec

Receives the transport error, or success.

webcpp::asio::basic_stream_socket::connect

Forwards connect, throwing on error.

Synopsis

void
connect(endpoint_type const& endpoint);

Parameters

Name Description

endpoint

The endpoint.

webcpp::asio::basic_stream_socket::connect

Forwards connect to the transport.

Synopsis

boost::system::error_code
connect(
    endpoint_type const& endpoint,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Parameters

Name Description

endpoint

The endpoint.

ec

Receives the transport error, or success.

webcpp::asio::basic_stream_socket::read_some

read_some overloads

Synopses

Forwards read_some, throwing on error.

template<class Buffers>
std::size_t
read_some(Buffers const& buffers);

Forwards read_some to the transport.

template<class Buffers>
std::size_t
read_some(
    Buffers const& buffers,
    boost::system::error_code& ec);

Return Value

  • The operation result.

  • The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

ec

Receives the transport error, or success.

webcpp::asio::basic_stream_socket::read_some

Forwards read_some, throwing on error.

Synopsis

template<class Buffers>
std::size_t
read_some(Buffers const& buffers);

Return Value

The operation result.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

webcpp::asio::basic_stream_socket::read_some

Forwards read_some to the transport.

Synopsis

template<class Buffers>
std::size_t
read_some(
    Buffers const& buffers,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

ec

Receives the transport error, or success.

webcpp::asio::basic_stream_socket::receive

receive overloads

Synopses

Uses receive with no message flags.

template<class Buffers>
std::size_t
receive(Buffers const& buffers);

Forwards receive, throwing on error.

template<class Buffers>
std::size_t
receive(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags);

Uses receive with no message flags.

template<class Buffers>
std::size_t
receive(
    Buffers const& buffers,
    boost::system::error_code& ec);

Forwards receive to the transport.

template<class Buffers>
std::size_t
receive(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    boost::system::error_code& ec);

Return Value

  • The byte count.

  • The operation result.

  • The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

ec

Receives the transport error, or success.

webcpp::asio::basic_stream_socket::receive

Uses receive with no message flags.

Synopsis

template<class Buffers>
std::size_t
receive(Buffers const& buffers);

Return Value

The byte count.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

webcpp::asio::basic_stream_socket::receive

Forwards receive, throwing on error.

Synopsis

template<class Buffers>
std::size_t
receive(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags);

Return Value

The operation result.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

webcpp::asio::basic_stream_socket::receive

Uses receive with no message flags.

Synopsis

template<class Buffers>
std::size_t
receive(
    Buffers const& buffers,
    boost::system::error_code& ec);

Return Value

The byte count.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

ec

Receives the transport error, or success.

webcpp::asio::basic_stream_socket::receive

Forwards receive to the transport.

Synopsis

template<class Buffers>
std::size_t
receive(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

ec

Receives the transport error, or success.

webcpp::asio::basic_stream_socket::send

send overloads

Synopses

Uses send with no message flags.

template<class Buffers>
std::size_t
send(Buffers const& buffers);

Forwards send, throwing on error.

template<class Buffers>
std::size_t
send(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags);

Uses send with no message flags.

template<class Buffers>
std::size_t
send(
    Buffers const& buffers,
    boost::system::error_code& ec);

Forwards send to the transport.

template<class Buffers>
std::size_t
send(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    boost::system::error_code& ec);

Return Value

  • The byte count.

  • The operation result.

  • The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

ec

Receives the transport error, or success.

webcpp::asio::basic_stream_socket::send

Uses send with no message flags.

Synopsis

template<class Buffers>
std::size_t
send(Buffers const& buffers);

Return Value

The byte count.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

webcpp::asio::basic_stream_socket::send

Forwards send, throwing on error.

Synopsis

template<class Buffers>
std::size_t
send(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags);

Return Value

The operation result.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

webcpp::asio::basic_stream_socket::send

Uses send with no message flags.

Synopsis

template<class Buffers>
std::size_t
send(
    Buffers const& buffers,
    boost::system::error_code& ec);

Return Value

The byte count.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

ec

Receives the transport error, or success.

webcpp::asio::basic_stream_socket::send

Forwards send to the transport.

Synopsis

template<class Buffers>
std::size_t
send(
    Buffers const& buffers,
    webcpp::asio_backend::socket_base::message_flags flags,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

flags

The flags.

ec

Receives the transport error, or success.

webcpp::asio::basic_stream_socket::shutdown

shutdown overloads

Synopses

Forwards shutdown, throwing on error.

void
shutdown(webcpp::asio_backend::socket_base::shutdown_type what);

Forwards shutdown to the transport.

boost::system::error_code
shutdown(
    webcpp::asio_backend::socket_base::shutdown_type what,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Parameters

Name Description

what

The what.

ec

Receives the transport error, or success.

webcpp::asio::basic_stream_socket::shutdown

Forwards shutdown, throwing on error.

Synopsis

void
shutdown(webcpp::asio_backend::socket_base::shutdown_type what);

Parameters

Name Description

what

The what.

webcpp::asio::basic_stream_socket::shutdown

Forwards shutdown to the transport.

Synopsis

boost::system::error_code
shutdown(
    webcpp::asio_backend::socket_base::shutdown_type what,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Parameters

Name Description

what

The what.

ec

Receives the transport error, or success.

webcpp::asio::basic_stream_socket::write_some

write_some overloads

Synopses

Forwards write_some, throwing on error.

template<class Buffers>
std::size_t
write_some(Buffers const& buffers);

Forwards write_some to the transport.

template<class Buffers>
std::size_t
write_some(
    Buffers const& buffers,
    boost::system::error_code& ec);

Return Value

  • The operation result.

  • The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

ec

Receives the transport error, or success.

webcpp::asio::basic_stream_socket::write_some

Forwards write_some, throwing on error.

Synopsis

template<class Buffers>
std::size_t
write_some(Buffers const& buffers);

Return Value

The operation result.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

webcpp::asio::basic_stream_socket::write_some

Forwards write_some to the transport.

Synopsis

template<class Buffers>
std::size_t
write_some(
    Buffers const& buffers,
    boost::system::error_code& ec);

Return Value

The result; ec receives any error.

Template Parameters

Name Description

Buffers

The operation type.

Parameters

Name Description

buffers

The buffers.

ec

Receives the transport error, or success.

webcpp::asio::basic_stream_socket::Unnamed using

Inherits executor, context, protocol and endpoint constructors.

Synopsis

using base::;

webcpp::asio::io_context

Boost.Asio’s io_context, whose run family on emscripten suspends into the browser’s event loop and yields to it after every turn of max_handlers_per_turn handlers.

Synopsis

class io_context
    : public webcpp::asio_backend::io_context

Description

On WASIp2/P3 it uses Boost’s run family, and its options change nothing. In a threaded browser build each context and its JavaScript bridge stay on their constructing thread. Other threads post through its executor; the run family rejects a runner on another thread. Multiple simultaneous runners of one browser context are unsupported because JavaScript values are thread-local.

Base Classes

Name Description

webcpp::asio_backend::io_context

Member Functions

Name Description

io_context [constructor]

Constructors

max_handlers_per_turn

max_handlers_per_turn overloads

run

Runs handlers until the io_context is out of work or stopped, yielding to the browser after every turn of max_handlers_per_turn handlers.

run_for

Runs handlers as run does, for rel_time at most.

run_one

Runs one handler, waiting in the browser’s event loop for one to be ready.

run_one_for

Runs one handler, waiting for rel_time at most.

run_one_until

Runs one handler, waiting until abs_time at most.

run_until

Runs handlers as run does, until abs_time at most.

See Also

"The run family", in the guide.

webcpp::asio::io_context::io_context

Constructors

Synopses

Constructs an io_context with the default options.

Constructs an io_context with options.

explicit
io_context(io_context_options options);

Constructs an io_context with Boost’s hint of the concurrency it will see.

explicit
io_context(
    int concurrency_hint,
    io_context_options options = {});

Constructs an io_context that allocates its services and its objects’ state with allocator.

template<class Allocator>
io_context(
    std::allocator_arg_t,
    Allocator const& allocator,
    io_context_options options = {});

Constructs an io_context with an allocator and Boost’s hint of its concurrency.

template<class Allocator>
io_context(
    std::allocator_arg_t,
    Allocator const& allocator,
    int concurrency_hint,
    io_context_options options = {});

Template Parameters

Name Description

Allocator

A standard allocator.

Parameters

Name Description

options

Its options.

concurrency_hint

Boost’s hint: 1, or BOOST_ASIO_CONCURRENCY_HINT_1, for one thread.

allocator

What the context allocates with.

webcpp::asio::io_context::io_context

Constructs an io_context with the default options.

Synopsis

io_context();

webcpp::asio::io_context::io_context

Constructs an io_context with options.

Synopsis

explicit
io_context(io_context_options options);

Parameters

Name Description

options

Its options.

webcpp::asio::io_context::io_context

Constructs an io_context with Boost’s hint of the concurrency it will see.

Synopsis

explicit
io_context(
    int concurrency_hint,
    io_context_options options = {});

Parameters

Name Description

concurrency_hint

Boost’s hint: 1, or BOOST_ASIO_CONCURRENCY_HINT_1, for one thread.

options

Its options.

webcpp::asio::io_context::io_context

Constructs an io_context that allocates its services and its objects’ state with allocator.

Synopsis

template<class Allocator>
io_context(
    std::allocator_arg_t,
    Allocator const& allocator,
    io_context_options options = {});

Template Parameters

Name Description

Allocator

A standard allocator.

Parameters

Name Description

allocator

What the context allocates with.

options

Its options.

webcpp::asio::io_context::io_context

Constructs an io_context with an allocator and Boost’s hint of its concurrency.

Synopsis

template<class Allocator>
io_context(
    std::allocator_arg_t,
    Allocator const& allocator,
    int concurrency_hint,
    io_context_options options = {});

Template Parameters

Name Description

Allocator

A standard allocator.

Parameters

Name Description

allocator

What the context allocates with.

concurrency_hint

Boost’s hint.

options

Its options.

webcpp::asio::io_context::max_handlers_per_turn

max_handlers_per_turn overloads

Synopses

The most handlers one turn runs.

[[nodiscard]]
std::size_t
max_handlers_per_turn() const noexcept;

Sets the most handlers one turn runs.

void
max_handlers_per_turn(std::size_t n) noexcept;

Return Value

The option’s value, at least 1.

Parameters

Name Description

n

The new value; 0 is taken as 1.

webcpp::asio::io_context::max_handlers_per_turn

The most handlers one turn runs.

Synopsis

[[nodiscard]]
std::size_t
max_handlers_per_turn() const noexcept;

Return Value

The option’s value, at least 1.

Note

The return value should not be discarded.

webcpp::asio::io_context::max_handlers_per_turn

Sets the most handlers one turn runs.

Synopsis

void
max_handlers_per_turn(std::size_t n) noexcept;

Parameters

Name Description

n

The new value; 0 is taken as 1.

webcpp::asio::io_context::run

Runs handlers until the io_context is out of work or stopped, yielding to the browser after every turn of max_handlers_per_turn handlers.

Synopsis

count_type
run();

Return Value

The handlers run.

webcpp::asio::io_context::run_for

Runs handlers as run does, for rel_time at most.

Synopsis

template<
    class Rep,
    class Period>
std::size_t
run_for(std::chrono::duration<Rep, Period> const& rel_time);

Return Value

The handlers run.

Template Parameters

Name Description

Rep

The duration’s representation.

Period

The duration’s period.

Parameters

Name Description

rel_time

How long.

webcpp::asio::io_context::run_one

Runs one handler, waiting in the browser’s event loop for one to be ready.

Synopsis

count_type
run_one();

Return Value

The handlers run: 1, or 0 when stopped or out of work.

webcpp::asio::io_context::run_one_for

Runs one handler, waiting for rel_time at most.

Synopsis

template<
    class Rep,
    class Period>
std::size_t
run_one_for(std::chrono::duration<Rep, Period> const& rel_time);

Return Value

The handlers run: 1 or 0.

Template Parameters

Name Description

Rep

The duration’s representation.

Period

The duration’s period.

Parameters

Name Description

rel_time

How long.

webcpp::asio::io_context::run_one_until

Runs one handler, waiting until abs_time at most.

Synopsis

template<
    class Clock,
    class Duration>
std::size_t
run_one_until(std::chrono::time_point<Clock, Duration> const& abs_time);

Return Value

The handlers run: 1 or 0.

Template Parameters

Name Description

Clock

The deadline’s clock.

Duration

The deadline’s duration.

Parameters

Name Description

abs_time

The deadline.

webcpp::asio::io_context::run_until

Runs handlers as run does, until abs_time at most.

Synopsis

template<
    class Clock,
    class Duration>
std::size_t
run_until(std::chrono::time_point<Clock, Duration> const& abs_time);

Return Value

The handlers run.

Template Parameters

Name Description

Clock

The deadline’s clock.

Duration

The deadline’s duration.

Parameters

Name Description

abs_time

The deadline.

webcpp::asio::io_context_options

The options of an io_context.

Synopsis

struct io_context_options;

Data Members

Name Description

max_handlers_per_turn

At most this many handlers run in one turn of the run family, which yields to the browser after a turn that reaches it.

webcpp::asio::io_context_options::max_handlers_per_turn

At most this many handlers run in one turn of the run family, which yields to the browser after a turn that reaches it.

Synopsis

std::size_t max_handlers_per_turn = WEBCPP_ASIO_DEFAULT_MAX_HANDLERS_PER_TURN;

Description

Defaults to WEBCPP_ASIO_DEFAULT_MAX_HANDLERS_PER_TURN. 0 is taken as 1.

webcpp::asio::tls_context_error

Errors produced while preparing an independently owned TLS client context.

Synopsis

enum class tls_context_error : int;

Members

Name Description

invalid_ca_bundle

The replacement contains no CAs, invalid PEM, or non-certificate data.

initialization_failed

OpenSSL could not allocate or initialize the requested context or trust store.

unsupported_target

The browser owns TLS and cannot use an OpenSSL client context.

webcpp::asio::make_error_code

Converts a TLS context preparation error to its stable error code.

Synopsis

boost::system::error_code
make_error_code(tls_context_error value) noexcept;

Description

Category equality is stable across native shared-library boundaries, including hidden visibility. The library defining a returned category must remain loaded while a caller uses the error code or its category’s virtual functions.

Return Value

The corresponding code in the webcpp.asio.tls category.

Parameters

Name Description

value

The context preparation error.

webcpp::asio::make_tls_client_context

make_tls_client_context overloads

Synopses

Creates a verifying TLS client context using WebCPP’s embedded Mozilla CA snapshot.

boost::system::result<ssl::context>
make_tls_client_context();

Creates a verifying TLS client context trusting only the supplied authorities.

boost::system::result<ssl::context>
make_tls_client_context(std::string_view ca_pem);

Return Value

The context, or a tls_context_error; browser targets return unsupported_target.

Parameters

Name Description

ca_pem

The complete replacement PEM authority set.

See Also

"How-to: configure trusted certificate authorities", in the guide.

webcpp::asio::make_tls_client_context

Creates a verifying TLS client context using WebCPP’s embedded Mozilla CA snapshot.

Synopsis

boost::system::result<ssl::context>
make_tls_client_context();

Description

No certificate files, system store, environment settings or network update are read. Updating embedded roots requires rebuilding and redeploying the program. The protocol floor, allocation and per-connection requirements are the same as the replacement overload. Link /webcpp/asio//tls to supply its dependencies.

Return Value

The context, or a tls_context_error; browser targets return unsupported_target.

See Also

"How-to: configure trusted certificate authorities", in the guide.

webcpp::asio::make_tls_client_context

Creates a verifying TLS client context trusting only the supplied authorities.

Synopsis

boost::system::result<ssl::context>
make_tls_client_context(std::string_view ca_pem);

Description

Native and WASIp2/P3 contexts require TLS 1.2 or newer and enable peer verification. Input consists of one or more PEM CA certificates separated only by whitespace. The certificates are copied into an independent OpenSSL store; input need not outlive this call. No system or bundled roots are added. No context is returned if any certificate is invalid. Configure hostname verification and SNI on each connection. OpenSSL owns allocations; no Asio allocator is used for its store.

Return Value

The context, or a tls_context_error; browser targets return unsupported_target.

Parameters

Name Description

ca_pem

The complete replacement PEM authority set.

See Also

"How-to: configure trusted certificate authorities", in the guide.

webcpp::asio::steady_timer

Boost.Asio’s timer on the monotonic clock, Boost’s own: on emscripten it waits in the reactor’s timer queue, which the run family waits on.

Synopsis

using webcpp::asio_backend::steady_timer;

webcpp::asio::system_timer

Boost.Asio’s timer on the system’s wall clock, Boost’s own: on emscripten it waits in the reactor’s timer queue, which the run family waits on.

Synopsis

using webcpp::asio_backend::system_timer;

WEBCPP_ASIO_BACKEND_DISABLE_THREADS

Disables internal thread support when the compiler has no pthread ABI.

Synopsis

#define WEBCPP_ASIO_BACKEND_DISABLE_THREADS

WEBCPP_ASIO_BACKEND_HEADER

Selects an implementation header for internal use.

Synopsis

#define WEBCPP_ASIO_BACKEND_HEADER(header)

Parameters

Name Description

header

The path relative to the backend include root.

WEBCPP_ASIO_DEFAULT_MAX_HANDLERS_PER_TURN

The default number of ready handlers processed in one turn on Emscripten.

Synopsis

Declared in <webcpp/asio/config.hpp>

#define WEBCPP_ASIO_DEFAULT_MAX_HANDLERS_PER_TURN

Description

Define this nonnegative integer on the compiler command line to replace 100. 0 is taken as 1 by io_context. Explicit context options override this default. Use the same definition in every translation unit, including Cobalt’s compiled runner, and rebuild when changing it. Natively it does not change scheduling. This is a handler count, not a time budget or a browser responsiveness guarantee.

See Also

"The run family", in the guide.

WEBCPP_ASIO_HANDLER_TYPE

Names the completion-handler type for a token and signature on the selected backend.

Synopsis

Declared in <webcpp/asio/config.hpp>

#define WEBCPP_ASIO_HANDLER_TYPE(Token, Signature)

Description

Include webcpp/asio/async_result.hpp before expanding this macro.

Parameters

Name Description

Token

The completion token type.

Signature

The completion signature.

WEBCPP_ASIO_HAS_BROWSER_BRIDGE

1 when Emscripten supplies the JavaScript event and Promise bridge; otherwise 0.

Synopsis

Declared in <webcpp/asio/config.hpp>

#define WEBCPP_ASIO_HAS_BROWSER_BRIDGE

WEBCPP_ASIO_HAS_BROWSER_WORKERS

1 for a pthread browser profile; isolation and worker availability are runtime facts.

Synopsis

Declared in <webcpp/asio/config.hpp>

#define WEBCPP_ASIO_HAS_BROWSER_WORKERS

WEBCPP_ASIO_HAS_CO_AWAIT

1 when the selected backend supports C++ coroutine completion tokens.

Synopsis

Declared in <webcpp/asio/config.hpp>

#define WEBCPP_ASIO_HAS_CO_AWAIT

WEBCPP_ASIO_HAS_HOST_DNS

1 when the host supplies forward address lookup; it does not imply reverse DNS.

Synopsis

Declared in <webcpp/asio/config.hpp>

#define WEBCPP_ASIO_HAS_HOST_DNS

WEBCPP_ASIO_HAS_LOCAL_SOCKETS

1 when native Boost.Asio enables local sockets; otherwise 0.

Synopsis

Declared in <webcpp/asio/config.hpp>

#define WEBCPP_ASIO_HAS_LOCAL_SOCKETS

WEBCPP_ASIO_HAS_OPENSSL_BACKEND

1 when this target can link the source-built OpenSSL provider; it does not select it.

Synopsis

Declared in <webcpp/asio/config.hpp>

#define WEBCPP_ASIO_HAS_OPENSSL_BACKEND

WEBCPP_ASIO_HAS_REVERSE_DNS

1 for native reverse lookup; WASI’s address lookup interface is forward-only.

Synopsis

Declared in <webcpp/asio/config.hpp>

#define WEBCPP_ASIO_HAS_REVERSE_DNS

WEBCPP_ASIO_HAS_SERIAL_PORT

1 when native Boost.Asio enables serial ports; otherwise 0.

Synopsis

Declared in <webcpp/asio/config.hpp>

#define WEBCPP_ASIO_HAS_SERIAL_PORT

WEBCPP_ASIO_HAS_SIGNALS

1 when native Boost.Asio enables process signals; WASI and browser events are not signals.

Synopsis

Declared in <webcpp/asio/config.hpp>

#define WEBCPP_ASIO_HAS_SIGNALS

WEBCPP_ASIO_HAS_SOCKET_BACKEND

1 when native or WASI socket APIs back TCP/UDP; grants and options remain runtime facts.

Synopsis

Declared in <webcpp/asio/config.hpp>

#define WEBCPP_ASIO_HAS_SOCKET_BACKEND

WEBCPP_ASIO_HAS_THREADS

1 when this Boost.Asio configuration enables threads, including cooperative threads.

Synopsis

Declared in <webcpp/asio/config.hpp>

#define WEBCPP_ASIO_HAS_THREADS

WEBCPP_ASIO_HAS_WASI_STDIO

1 when the pollable WASIp2 CLI stream adapter is available; otherwise 0.

Synopsis

Declared in <webcpp/asio/config.hpp>

#define WEBCPP_ASIO_HAS_WASI_STDIO

WEBCPP_ASIO_NO_EXCEPTIONS

Selects the exception-free interface of WebCPP-owned adapters.

Synopsis

Declared in <webcpp/asio/config.hpp>

#define WEBCPP_ASIO_NO_EXCEPTIONS

Description

Defined automatically when WEBCPP_HAS_EXCEPTIONS is not defined. A developer may also define it explicitly; WEBCPP_NO_EXCEPTIONS selects the corresponding collection-wide policy. These macros do not change the compiler’s exception mode.

Browser socket, resolver and SSL adapters omit their throwing overloads under this policy. Native Boost APIs and the shipped upstream-derived WASI backend retain their overload sets. Without compiler exception support, calling a retained throwing overload on an error can terminate the process. Use explicit error_code overloads or asynchronous error/result channels for recovery.

See Also

"Testing", in the guide.

Appendix A: Changelog

Changes prepared for the first WebCPP release.

Unreleased

  • Fixed browser turn budgets across timer waits so worker proxy messages can run.

  • Fixed browser and WASIp2 timer test dependencies and the unbounded backend control.

  • Improved exception analysis of system executor initialization without changing fatal behavior.

  • Fixed posted completions after JavaScript reentry with concurrency hint one.

  • Added current example coverage and Release performance, memory and yield measurements.

webcpp 0.1.0

  • Added Boost.Asio contexts and timers with browser event-loop suspension.

  • Added browser workers, main-thread handoff and turns defaulting to 100 handlers.

  • Added Promise and DOM-event operations with cancellation and allocator support.

  • Added browser socket adapters, retained resolver names and TLS settings.

  • Added WASIp2/P3 networking, UDP gather/scatter and asynchronous forward DNS.

  • Added Cobalt, CLI streams, WASI TLS and P3 cooperative-thread integration.

  • Added optional source-built OpenSSL and replaceable embedded CA certificates.

  • Fixed Cobalt TLS state/cancellation and TLS error equality across shared libraries.

  • Added capability guards and fixed configuration propagation and resolver allocation.

  • Added Diataxis guides, compiled examples and MrDocs API reference.