|
|
@ -28,6 +28,7 @@ |
|
|
|
#include "src/core/lib/gprpp/debug_location.h" |
|
|
|
#include "src/core/lib/gprpp/debug_location.h" |
|
|
|
#include "src/core/lib/gprpp/down_cast.h" |
|
|
|
#include "src/core/lib/gprpp/down_cast.h" |
|
|
|
#include "src/core/lib/gprpp/orphanable.h" |
|
|
|
#include "src/core/lib/gprpp/orphanable.h" |
|
|
|
|
|
|
|
#include "src/core/lib/gprpp/ref_counted.h" |
|
|
|
#include "src/core/lib/gprpp/ref_counted_ptr.h" |
|
|
|
#include "src/core/lib/gprpp/ref_counted_ptr.h" |
|
|
|
|
|
|
|
|
|
|
|
namespace grpc_core { |
|
|
|
namespace grpc_core { |
|
|
@ -46,15 +47,16 @@ namespace grpc_core { |
|
|
|
//
|
|
|
|
//
|
|
|
|
// This will be used by CRTP (curiously-recurring template pattern), e.g.:
|
|
|
|
// This will be used by CRTP (curiously-recurring template pattern), e.g.:
|
|
|
|
// class MyClass : public RefCounted<MyClass> { ... };
|
|
|
|
// class MyClass : public RefCounted<MyClass> { ... };
|
|
|
|
template <typename Child> |
|
|
|
//
|
|
|
|
class DualRefCounted { |
|
|
|
// Impl & UnrefBehavior are as per RefCounted.
|
|
|
|
|
|
|
|
template <typename Child, typename Impl = PolymorphicRefCount, |
|
|
|
|
|
|
|
typename UnrefBehavior = UnrefDelete> |
|
|
|
|
|
|
|
class DualRefCounted : public Impl { |
|
|
|
public: |
|
|
|
public: |
|
|
|
// Not copyable nor movable.
|
|
|
|
// Not copyable nor movable.
|
|
|
|
DualRefCounted(const DualRefCounted&) = delete; |
|
|
|
DualRefCounted(const DualRefCounted&) = delete; |
|
|
|
DualRefCounted& operator=(const DualRefCounted&) = delete; |
|
|
|
DualRefCounted& operator=(const DualRefCounted&) = delete; |
|
|
|
|
|
|
|
|
|
|
|
virtual ~DualRefCounted() = default; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GRPC_MUST_USE_RESULT RefCountedPtr<Child> Ref() { |
|
|
|
GRPC_MUST_USE_RESULT RefCountedPtr<Child> Ref() { |
|
|
|
IncrementRefCount(); |
|
|
|
IncrementRefCount(); |
|
|
|
return RefCountedPtr<Child>(static_cast<Child*>(this)); |
|
|
|
return RefCountedPtr<Child>(static_cast<Child*>(this)); |
|
|
@ -215,7 +217,7 @@ class DualRefCounted { |
|
|
|
CHECK_GT(weak_refs, 0u); |
|
|
|
CHECK_GT(weak_refs, 0u); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
if (GPR_UNLIKELY(prev_ref_pair == MakeRefPair(0, 1))) { |
|
|
|
if (GPR_UNLIKELY(prev_ref_pair == MakeRefPair(0, 1))) { |
|
|
|
delete static_cast<Child*>(this); |
|
|
|
unref_behavior_(static_cast<Child*>(this)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
void WeakUnref(const DebugLocation& location, const char* reason) { |
|
|
|
void WeakUnref(const DebugLocation& location, const char* reason) { |
|
|
@ -242,7 +244,7 @@ class DualRefCounted { |
|
|
|
(void)reason; |
|
|
|
(void)reason; |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
if (GPR_UNLIKELY(prev_ref_pair == MakeRefPair(0, 1))) { |
|
|
|
if (GPR_UNLIKELY(prev_ref_pair == MakeRefPair(0, 1))) { |
|
|
|
delete static_cast<Child*>(this); |
|
|
|
unref_behavior_(static_cast<const Child*>(this)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -266,6 +268,9 @@ class DualRefCounted { |
|
|
|
// Ref count has dropped to zero, so the object is now orphaned.
|
|
|
|
// Ref count has dropped to zero, so the object is now orphaned.
|
|
|
|
virtual void Orphaned() = 0; |
|
|
|
virtual void Orphaned() = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Note: Depending on the Impl used, this dtor can be implicitly virtual.
|
|
|
|
|
|
|
|
~DualRefCounted() = default; |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
private: |
|
|
|
// Allow RefCountedPtr<> to access IncrementRefCount().
|
|
|
|
// Allow RefCountedPtr<> to access IncrementRefCount().
|
|
|
|
template <typename T> |
|
|
|
template <typename T> |
|
|
@ -358,6 +363,7 @@ class DualRefCounted { |
|
|
|
const char* trace_; |
|
|
|
const char* trace_; |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
std::atomic<uint64_t> refs_{0}; |
|
|
|
std::atomic<uint64_t> refs_{0}; |
|
|
|
|
|
|
|
GPR_NO_UNIQUE_ADDRESS UnrefBehavior unref_behavior_; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
} // namespace grpc_core
|
|
|
|
} // namespace grpc_core
|
|
|
|