// // // Copyright 2017 gRPC 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 GRPC_SRC_CORE_LIB_GPRPP_REF_COUNTED_H #define GRPC_SRC_CORE_LIB_GPRPP_REF_COUNTED_H #include <grpc/support/port_platform.h> #include <atomic> #include <cassert> #include <cinttypes> #include <grpc/support/log.h> #include "src/core/lib/gprpp/atomic_utils.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" namespace grpc_core { // RefCount is a simple atomic ref-count. // // This is a C++ implementation of gpr_refcount, with inline functions. Due to // inline functions, this class is significantly more efficient than // gpr_refcount and should be preferred over gpr_refcount whenever possible. // // TODO(soheil): Remove gpr_refcount after submitting the GRFC and the paragraph // above. class RefCount { … }; // PolymorphicRefCount enforces polymorphic destruction of RefCounted. class PolymorphicRefCount { … }; // NonPolymorphicRefCount does not enforce polymorphic destruction of // RefCounted. Please refer to RefCounted for more details, and // when in doubt use PolymorphicRefCount. class NonPolymorphicRefCount { … }; // Behavior of RefCounted<> upon ref count reaching 0. enum UnrefBehavior { … }; namespace internal { template <typename T, UnrefBehavior UnrefBehaviorArg> class Delete; Delete<T, kUnrefDelete>; Delete<T, kUnrefNoDelete>; Delete<T, kUnrefCallDtor>; } // namespace internal // A base class for reference-counted objects. // New objects should be created via new and start with a refcount of 1. // When the refcount reaches 0, executes the specified UnrefBehavior. // // This will commonly be used by CRTP (curiously-recurring template pattern) // e.g., class MyClass : public RefCounted<MyClass> // // Use PolymorphicRefCount and NonPolymorphicRefCount to select between // different implementations of RefCounted. // // Note that NonPolymorphicRefCount does not support polymorphic destruction. // So, use NonPolymorphicRefCount only when both of the following conditions // are guaranteed to hold: // (a) Child is a concrete leaf class in RefCounted<Child>, and // (b) you are guaranteed to call Unref only on concrete leaf classes and not // their parents. // // The following example is illegal, because calling Unref() will not call // the dtor of Child. // // class Parent : public RefCounted<Parent, NonPolymorphicRefCount> {} // class Child : public Parent {} // // Child* ch; // ch->Unref(); // template <typename Child, typename Impl = PolymorphicRefCount, UnrefBehavior UnrefBehaviorArg = kUnrefDelete> class RefCounted : public Impl { … }; } // namespace grpc_core #endif // GRPC_SRC_CORE_LIB_GPRPP_REF_COUNTED_H