1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- [/
- / 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]
|