90 lines
3.4 KiB
Plaintext
90 lines
3.4 KiB
Plaintext
[/
|
|
/ Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
|
/
|
|
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
/]
|
|
|
|
[section:allocation Custom Memory Allocation]
|
|
|
|
Many asynchronous operations need to allocate an object to store state
|
|
associated with the operation. For example, a Win32 implementation needs
|
|
`OVERLAPPED`-derived objects to pass to Win32 API functions.
|
|
|
|
Furthermore, programs typically contain easily identifiable chains of
|
|
asynchronous operations. A half duplex protocol implementation (e.g. an HTTP
|
|
server) would have a single chain of operations per client (receives followed
|
|
by sends). A full duplex protocol implementation would have two chains
|
|
executing in parallel. Programs should be able to leverage this knowledge to
|
|
reuse memory for all asynchronous operations in a chain.
|
|
|
|
Given a copy of a user-defined `Handler` object `h`, if the implementation
|
|
needs to allocate memory associated with that handler it will obtain an
|
|
allocator using the `get_associated_allocator` function. For example:
|
|
|
|
boost::asio::associated_allocator_t<Handler> a = boost::asio::get_associated_allocator(h);
|
|
|
|
The associated allocator must satisfy the standard Allocator requirements.
|
|
|
|
By default, handlers use the standard allocator (which is implemented in terms
|
|
of `::operator new()` and `::operator delete()`). The allocator may be
|
|
customised for a particular handler type by specifying a nested type
|
|
`allocator_type` and member function `get_allocator()`:
|
|
|
|
class my_handler
|
|
{
|
|
public:
|
|
// Custom implementation of Allocator type requirements.
|
|
typedef my_allocator allocator_type;
|
|
|
|
// Return a custom allocator implementation.
|
|
allocator_type get_allocator() const noexcept
|
|
{
|
|
return my_allocator();
|
|
}
|
|
|
|
void operator()() { ... }
|
|
};
|
|
|
|
In more complex cases, the `associated_allocator` template may be partially
|
|
specialised directly:
|
|
|
|
namespace boost { namespace asio {
|
|
|
|
template <typename Allocator>
|
|
struct associated_allocator<my_handler, Allocator>
|
|
{
|
|
// Custom implementation of Allocator type requirements.
|
|
typedef my_allocator type;
|
|
|
|
// Return a custom allocator implementation.
|
|
static type get(const my_handler&,
|
|
const Allocator& a = Allocator()) noexcept
|
|
{
|
|
return my_allocator();
|
|
}
|
|
};
|
|
|
|
} } // namespace boost::asio
|
|
|
|
The implementation guarantees that the deallocation will occur before the
|
|
associated handler is invoked, which means the memory is ready to be reused for
|
|
any new asynchronous operations started by the handler.
|
|
|
|
The custom memory allocation functions may be called from any user-created
|
|
thread that is calling a library function. The implementation guarantees that,
|
|
for the asynchronous operations included the library, the implementation will
|
|
not make concurrent calls to the memory allocation functions for that handler.
|
|
The implementation will insert appropriate memory barriers to ensure correct
|
|
memory visibility should allocation functions need to be called from different
|
|
threads.
|
|
|
|
[heading See Also]
|
|
|
|
[link boost_asio.reference.associated_allocator associated_allocator],
|
|
[link boost_asio.reference.get_associated_allocator get_associated_allocator],
|
|
[link boost_asio.examples.cpp03_examples.allocation custom memory allocation example (C++03)],
|
|
[link boost_asio.examples.cpp11_examples.allocation custom memory allocation example (C++11)].
|
|
|
|
[endsect]
|