chromium/third_party/crashpad/crashpad/client/ring_buffer_annotation.h

// Copyright 2023 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef CRASHPAD_CLIENT_RING_BUFFER_ANNOTATION_H_
#define CRASHPAD_CLIENT_RING_BUFFER_ANNOTATION_H_

#include <stdio.h>

#include "client/annotation.h"
#include "client/length_delimited_ring_buffer.h"

namespace crashpad {

//! \brief Capacity of `RingBufferAnnotation`, in bytes.
RingBufferAnnotationCapacity;

namespace internal {

//! \brief Default capacity of `RingBufferAnnotation`, in bytes.
inline constexpr RingBufferAnnotationCapacity
    kDefaultRingBufferAnnotationCapacity =;

}  // namespace internal

//! \brief An `Annotation` which wraps a `LengthDelimitedRingBuffer`
//!     of up to `Capacity` bytes in length.
//!
//! Supports writing variable-length data via `Push()`. When the ring buffer is
//! full, it will drop old data items in FIFO order until enough space is
//! available for the write.
//!
//! Supports guarding concurrent reads from writes via `ScopedSpinGuard`, so
//! writing to this object is thread-safe.
//!
//! Clients which read this `Annotation`'s memory can optionally invoke
//! `TryCreateScopedSpinGuard()` on this object to ensure any pending write
//! finishes before the memory is read.
//!
//! Each item in this ring buffer is delimited by its length encoded in
//! little-endian Base 128 varint encoding.
//!
//! `RingBufferAnnotation` uses varint-encoded delimiters to enable
//! zero-copy deserialization of the ringbuffer's contents when storing
//! protobufs inside the ringbuffer, e.g. via
//! `google::protobuf::util::ParseDelimitedFromZeroCopyStream()` or similar.
//!
//! \sa
//! https://github.com/protocolbuffers/protobuf/blob/3202b9da88ceb75b65bbabaf4033c95e872f828d/src/google/protobuf/util/delimited_message_util.h#L85
//! \sa
//! https://github.com/protocolbuffers/protobuf/blob/8bd49dea5e167a389d94b71d24c981d8f9fa0c99/src/google/protobuf/io/zero_copy_stream_impl_lite.h#L68
//! \sa
//! https://github.com/protocolbuffers/protobuf/blob/8bd49dea5e167a389d94b71d24c981d8f9fa0c99/src/google/protobuf/io/coded_stream.h#L171
//!
//! To deserialize the items stored in this annotation, use
//! `LengthDelimitedRingBufferReader`.
template <RingBufferAnnotationCapacity Capacity =
              internal::kDefaultRingBufferAnnotationCapacity>
class RingBufferAnnotation final : public Annotation {};

// Allow just `RingBufferAnnotation foo;` to be declared without template
// arguments using C++17 class template argument deduction.
template <RingBufferAnnotationCapacity Capacity =
              internal::kDefaultRingBufferAnnotationCapacity>
RingBufferAnnotation(Annotation::Type type, const char name[])
    -> RingBufferAnnotation<Capacity>;

}  // namespace crashpad

#endif  // CRASHPAD_CLIENT_RING_BUFFER_ANNOTATION_H_