// 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_UTIL_REF_COUNTED_H_ #define IPCZ_SRC_UTIL_REF_COUNTED_H_ #include <algorithm> #include <atomic> #include <cstddef> #include <type_traits> #include <utility> #include "third_party/abseil-cpp/absl/base/macros.h" namespace ipcz { namespace internal { // Base class for RefCounted<T> instances. See that definition below. class RefCountedBase { … }; } // namespace internal // Tag used to construct a Ref<T> which does not increase ref-count. enum { … }; // Base class for any ref-counted type T whose ownership can be shared by any // number of Ref<T> objects. template <typename T> class RefCounted : public internal::RefCountedBase { … }; // A smart pointer which can be used to share ownership of an instance of T, // where T is any type derived from RefCounted above. // // This is used instead of std::shared_ptr so that ipcz can release and // re-acquire ownership of individual references, as some object references may // be conceptually owned by the embedding application via an IpczHandle across // ipcz ABI boundary. std::shared_ptr design does not allow for such manual ref // manipulation without additional indirection. template <typename T> class Ref { … }; // Wraps `ptr` as a Ref<T>, increasing the refcount by 1. template <typename T> Ref<T> WrapRefCounted(T* ptr) { … } // Wraps `ptr` as a Ref<T>, assuming ownership of an existing reference. Does // not change the object's refcount. template <typename T> Ref<T> AdoptRef(T* ptr) { … } template <typename T, typename... Args> Ref<T> MakeRefCounted(Args&&... args) { … } } // namespace ipcz #endif // IPCZ_SRC_UTIL_REF_COUNTED_H_