chromium/third_party/ipcz/src/ipcz/fragment_ref.h

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

#ifndef IPCZ_SRC_IPCZ_FRAGMENT_REF_H_
#define IPCZ_SRC_IPCZ_FRAGMENT_REF_H_

#include <algorithm>
#include <type_traits>
#include <utility>

#include "ipcz/fragment.h"
#include "ipcz/fragment_descriptor.h"
#include "ipcz/ref_counted_fragment.h"
#include "third_party/abseil-cpp/absl/base/macros.h"
#include "util/ref_counted.h"

namespace ipcz {

class NodeLinkMemory;

namespace internal {

// Base class for any FragmentRef<T>, implementing common behavior for managing
// the underlying RefCountedFragment.
class GenericFragmentRef {};

}  // namespace internal

// Holds a reference to a RefCountedFragment. When this object is destroyed, the
// underlying ref count is decreased. If the ref count is decreased to zero, the
// underlying Fragment is returned to its NodeLinkMemory.
//
// Some FragmentRefs may be designated as "unmanaged", meaning that they will
// never attempt to free the underlying Fragment. These refs are used to
// preserve type compatibility with other similar (but managed) FragmentRefs
// when the underlying Fragment isn't dynamically allocated and can't be freed.
//
// For example most RouterLinkState fragments are dynamically allocated and
// managed by FragmentRefs, but some instances are allocated at fixed locations
// within the NodeLinkMemory and cannot be freed or reused. In both cases, ipcz
// can refer to these objects using a FragmentRef<RouterLinkState>.
template <typename T>
class FragmentRef : public internal::GenericFragmentRef {};

}  // namespace ipcz

#endif  // IPCZ_SRC_IPCZ_FRAGMENT_REF_H_