#### Allocators

Every asynchronous agent has an associated allocator. An agent's allocator is an interface used by the agent's asynchronous operations to obtain per-operation stable memory resources (POSMs). This name reflects the fact that the memory is per-operation because the memory is only retained for the lifetime of that operation, and stable, because the memory is guaranteed to be available at that location throughout the operation.

Asynchronous operations may utilise POSMs in a number of different ways:

- The operation doesn't require any POSMs. For example, the operation wraps an existing API that performs its own memory management, or is copying the long lived state into existing memory like a circular buffer.
- The operation uses a single, fixed-size POSM for as long as the operation is outstanding. For example, the operation stores some state in a linked list.
- The operation uses a single, runtime-sized POSM. For example, the operation stores a copy of a user-supplied buffer, or a runtime-sized array of iovec structures.
- The operation uses multiple POSMs concurrently. For example, a fixed size POSM for a linked list plus a runtime-sized POSM for a buffer.
- The operation uses multiple POSMs serially, which may vary in size.

Associated allocators allow users to treat POSM optimisation as a cross-cutting concern to the composition of asynchronous operations. Furthermore, using allocators as the interface to obtain POSMs grant substantial flexibility to both the implementers and users of asynchronous operations:

- Users can ignore the allocator and accept whatever default strategy is employed by the application.
- Implementers can ignore the allocator, especially if the operation is not considered performance-sensitive.
- Users can co-locate POSMs for related asynchronous operations, for better locality of reference.
- For compositions that involve serial POSMs of different sizes, memory usage need only be as great as the currently extant POSM. For example, consider a composition that contains a short-lived operation that uses large POSMs (connection establishment and handshake) followed by a long-lived operation that uses small POSMs (transferring data to and from the peer).

As noted previously, all resources must be released prior to calling the completion handler. This enables memory to be recycled for subsequent asynchronous operations within an agent. This allows applications with long-lived asynchronous agents to have no hot-path memory allocations, even though the user code is unaware of associated allocators.

###### See Also

Custom Memory Allocation.