|
|
|
@ -34,14 +34,58 @@ |
|
|
|
|
|
|
|
|
|
namespace grpc_core { |
|
|
|
|
|
|
|
|
|
// PolymorphicRefCount enforces polymorphic destruction of RefCounted.
|
|
|
|
|
class PolymorphicRefCount { |
|
|
|
|
public: |
|
|
|
|
GRPC_ABSTRACT_BASE_CLASS |
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE |
|
|
|
|
|
|
|
|
|
virtual ~PolymorphicRefCount() {} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// NonPolymorphicRefCount does not enforce polymorphic destruction of
|
|
|
|
|
// RefCounted. Please refer to grpc_core::RefCounted for more details, and
|
|
|
|
|
// when in doubt use PolymorphicRefCount.
|
|
|
|
|
class NonPolymorphicRefCount { |
|
|
|
|
public: |
|
|
|
|
GRPC_ABSTRACT_BASE_CLASS |
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE |
|
|
|
|
|
|
|
|
|
~NonPolymorphicRefCount() {} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 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, the object will be deleted via Delete().
|
|
|
|
|
//
|
|
|
|
|
// This will commonly be used by CRTP (curiously-recurring template pattern)
|
|
|
|
|
// e.g., class MyClass : public RefCounted<MyClass>
|
|
|
|
|
template <typename Child> |
|
|
|
|
class RefCounted { |
|
|
|
|
//
|
|
|
|
|
// 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 gauranteed 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> |
|
|
|
|
class RefCounted : public Impl { |
|
|
|
|
public: |
|
|
|
|
RefCountedPtr<Child> Ref() GRPC_MUST_USE_RESULT { |
|
|
|
|
IncrementRefCount(); |
|
|
|
@ -69,7 +113,8 @@ class RefCounted { |
|
|
|
|
|
|
|
|
|
RefCounted() { gpr_ref_init(&refs_, 1); } |
|
|
|
|
|
|
|
|
|
virtual ~RefCounted() {} |
|
|
|
|
// Note: Depending on the Impl used, this dtor can be implicitly virtual.
|
|
|
|
|
~RefCounted() {} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
// Allow RefCountedPtr<> to access IncrementRefCount().
|
|
|
|
@ -87,8 +132,8 @@ class RefCounted { |
|
|
|
|
// pointers and legacy code that is manually calling Ref() and Unref().
|
|
|
|
|
// Once all of our code is converted to idiomatic C++, we may be able to
|
|
|
|
|
// eliminate this class.
|
|
|
|
|
template <typename Child> |
|
|
|
|
class RefCountedWithTracing { |
|
|
|
|
template <typename Child, typename Impl = PolymorphicRefCount> |
|
|
|
|
class RefCountedWithTracing : public Impl { |
|
|
|
|
public: |
|
|
|
|
RefCountedPtr<Child> Ref() GRPC_MUST_USE_RESULT { |
|
|
|
|
IncrementRefCount(); |
|
|
|
@ -149,7 +194,8 @@ class RefCountedWithTracing { |
|
|
|
|
: RefCountedWithTracing() {} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
virtual ~RefCountedWithTracing() {} |
|
|
|
|
// Note: Depending on the Impl used, this dtor can be implicitly virtual.
|
|
|
|
|
~RefCountedWithTracing() {} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
// Allow RefCountedPtr<> to access IncrementRefCount().
|
|
|
|
|