Shared Buffer
Loading...
Searching...
No Matches
Reference Counted Byte Buffer Classes, Const and Mutable Versions

Overview

The shared_buffer classes provide byte buffers with internal reference counting. These classes can be used within asynchronous IO / networking applications where the lifetime of the buffer must be kept alive until a requested IO operation completes.

For example, a network write is started asynchronously, which means a write request is started, and the write completion will happen at a later time. The byte buffer must be kept alive until the completion notification. Meanwhile multiple other write requests can happen simultaneously (even on the same thread). For reads, a read request can be started, and the byte buffer used for incoming data will be kept alive until a read request completes - i.e. data arrives.

In networking applications, this allows multiple sockets to be performing reads and writes under one thread (or multiple threads, such as in a thread pool). In particular, it eliminates the (sometimes inefficient) design of "one thread per socket".

The Connective C++ Chops Net IP library is an asynchronous networking library (using Asio underneath) and it uses shared_buffer classes for buffer lifetime management.

There are two concrete classes, mutable_shared_buffer and const_shared_buffer. mutable_shared_buffer is a reference counted modifiable buffer class with convenience methods for appending data. const_shared_buffer is a reference counted non-modifiable buffer class. Once the object is constructed, it cannot be modified.

A const_shared_buffer can be efficiently constructed (no buffer copies) from a mutable shared_buffer. This allows the use case of serializing data into a mutable_shared_buffer then constructing a const_shared_buffer for writing to the network.

Besides the data buffer lifetime management, these utility classes eliminate data copies and (obviously) do not have to be used only in networking use cases.

Additional Details

Internally all data is stored in a std::vector of std::byte. There are convenience templated constructors so that the shared_buffer objects can be constructed from traditional byte buffers, such as char *.

There are ordering methods so that shared buffer objects can be stored in sequential or associative containers.

Efficient moving of data (versus copying) is enabled in multiple ways, including allowing a const_shared_buffer to be move constructed from a mutable_shared_buffer, and allowing a std::vector of std::byte to be moved into either shared_buffer type.

The implementation is adapted from Chris Kohlhoff's reference counted buffer examples in the Asio library. It has been significantly modified by adding a mutable_shared_buffer class as well as adding convenience methods to the const_shared_buffer class.

It is likely that this shared buffer design and code will change as the C++ Networking TS buffer features are expanded, changed, or better understood. Currently there are no direct ties to Networking TS buffer features.

Note
Everything is declared noexcept except for the methods that allocate memory and might throw a memory exception. This is tighter than the noexcept declarations on the underlying std::vector methods, since std::byte operations will never throw.
Authors
Cliff Green, Chris Kohlhoff

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)