chromium/net/base/datagram_buffer.h

// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_BASE_DATAGRAM_BUFFER_H_
#define NET_BASE_DATAGRAM_BUFFER_H_

#include <list>

#include "base/memory/weak_ptr.h"
#include "net/base/net_export.h"

namespace net {

// An IO buffer, (at least initially) specifically for use with the
// new DatagramClientSocket::WriteAsync method, with the following key
// features:
//
//   1) Meant to be easily batched when that improves efficiency. The
//      primary goal of WriteAsync is to enable enlisting an
//      additional cpu core for the kernel part of socket write.
//   2) Uses unique_ptr (with std::move) rather than reference
//      counting as in IOBuffers.  The benefit is safer cancellation
//      semantics, IOBuffer used reference count to enforce unique
//      ownership in an idiomatic fashion.  unique_ptr is ligher weight
//      as it doesn't use thread safe primitives as
//      RefCountedThreadSafe does.
//   3) Provides a pooling allocator, which for datagram buffers is
//      much cheaper than using fully general allocator (e.g. malloc
//      etc.).  The implementation takes advantage of
//      std::list::splice so that costs associated with allocations
//      and copies of pool metadata quickly amortize to zero, and all
//      common operations are O(1).

class DatagramBuffer;

// Batches of DatagramBuffers are treated as a FIFO queue, implemented
// by |std::list|.  Note that |std::list::splice()| is attractive for
// this use case because it keeps most operations to O(1) and
// minimizes allocations/frees and copies.
DatagramBuffers;

class NET_EXPORT_PRIVATE DatagramBufferPool {};

// |DatagramBuffer|s can only be created via
// |DatagramBufferPool::Enqueue()|.
//

// |DatagramBuffer|s should be recycled via
// |DatagramBufferPool::Dequeue|.  Care must be taken when a
// |DatagramBuffer| is moved to another thread via
// |PostTask|. |Dequeue| is not expected to be thread-safe, so it
// is preferred to move the |DatagramBuffer|s back to the thread where
// the pool lives (e.g. using |PostTaskAndReturnWithResult|) and
// dequeuing them from there.  In the exception of pathalogical
// cancellation (e.g. due to thread tear-down), the destructor will
// release its memory permanently rather than returning to the pool.
class NET_EXPORT_PRIVATE DatagramBuffer {};

}  // namespace net

#endif  // NET_BASE_DATAGRAM_BUFFER_H_