chromium/third_party/grpc/src/src/core/lib/gprpp/ref_counted.h

//
//
// 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