|
|
|
@ -28,6 +28,7 @@ |
|
|
|
|
#include "src/core/lib/gprpp/abstract.h" |
|
|
|
|
#include "src/core/lib/gprpp/debug_location.h" |
|
|
|
|
#include "src/core/lib/gprpp/memory.h" |
|
|
|
|
#include "src/core/lib/gprpp/ref_counted_ptr.h" |
|
|
|
|
|
|
|
|
|
namespace grpc_core { |
|
|
|
|
|
|
|
|
@ -69,6 +70,7 @@ inline OrphanablePtr<T> MakeOrphanable(Args&&... args) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// A type of Orphanable with internal ref-counting.
|
|
|
|
|
template <typename Child> |
|
|
|
|
class InternallyRefCounted : public Orphanable { |
|
|
|
|
public: |
|
|
|
|
// Not copyable nor movable.
|
|
|
|
@ -78,10 +80,20 @@ class InternallyRefCounted : public Orphanable { |
|
|
|
|
GRPC_ABSTRACT_BASE_CLASS |
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
// Allow Delete() to access destructor.
|
|
|
|
|
template <typename T> |
|
|
|
|
friend void Delete(T*); |
|
|
|
|
|
|
|
|
|
// Allow RefCountedPtr<> to access Unref() and IncrementRefCount().
|
|
|
|
|
friend class RefCountedPtr<Child>; |
|
|
|
|
|
|
|
|
|
InternallyRefCounted() { gpr_ref_init(&refs_, 1); } |
|
|
|
|
virtual ~InternallyRefCounted() {} |
|
|
|
|
|
|
|
|
|
void Ref() { gpr_ref(&refs_); } |
|
|
|
|
RefCountedPtr<Child> Ref() GRPC_MUST_USE_RESULT { |
|
|
|
|
IncrementRefCount(); |
|
|
|
|
return RefCountedPtr<Child>(reinterpret_cast<Child*>(this)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Unref() { |
|
|
|
|
if (gpr_unref(&refs_)) { |
|
|
|
@ -89,11 +101,9 @@ class InternallyRefCounted : public Orphanable { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Allow Delete() to access destructor.
|
|
|
|
|
template <typename T> |
|
|
|
|
friend void Delete(T*); |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
void IncrementRefCount() { gpr_ref(&refs_); } |
|
|
|
|
|
|
|
|
|
gpr_refcount refs_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -103,6 +113,7 @@ class InternallyRefCounted : public Orphanable { |
|
|
|
|
// 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 InternallyRefCountedWithTracing : public Orphanable { |
|
|
|
|
public: |
|
|
|
|
// Not copyable nor movable.
|
|
|
|
@ -118,6 +129,9 @@ class InternallyRefCountedWithTracing : public Orphanable { |
|
|
|
|
template <typename T> |
|
|
|
|
friend void Delete(T*); |
|
|
|
|
|
|
|
|
|
// Allow RefCountedPtr<> to access Unref() and IncrementRefCount().
|
|
|
|
|
friend class RefCountedPtr<Child>; |
|
|
|
|
|
|
|
|
|
InternallyRefCountedWithTracing() |
|
|
|
|
: InternallyRefCountedWithTracing(static_cast<TraceFlag*>(nullptr)) {} |
|
|
|
|
|
|
|
|
@ -133,18 +147,27 @@ class InternallyRefCountedWithTracing : public Orphanable { |
|
|
|
|
|
|
|
|
|
virtual ~InternallyRefCountedWithTracing() {} |
|
|
|
|
|
|
|
|
|
void Ref() { gpr_ref(&refs_); } |
|
|
|
|
RefCountedPtr<Child> Ref() GRPC_MUST_USE_RESULT { |
|
|
|
|
IncrementRefCount(); |
|
|
|
|
return RefCountedPtr<Child>(reinterpret_cast<Child*>(this)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Ref(const DebugLocation& location, const char* reason) { |
|
|
|
|
RefCountedPtr<Child> Ref(const DebugLocation& location, |
|
|
|
|
const char* reason) GRPC_MUST_USE_RESULT { |
|
|
|
|
if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { |
|
|
|
|
gpr_atm old_refs = gpr_atm_no_barrier_load(&refs_.count); |
|
|
|
|
gpr_log(GPR_DEBUG, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s", |
|
|
|
|
trace_flag_->name(), this, location.file(), location.line(), |
|
|
|
|
old_refs, old_refs + 1, reason); |
|
|
|
|
} |
|
|
|
|
Ref(); |
|
|
|
|
return Ref(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO(roth): Once all of our code is converted to C++ and can use
|
|
|
|
|
// RefCountedPtr<> instead of manual ref-counting, make the Unref() methods
|
|
|
|
|
// private, since they will only be used by RefCountedPtr<>, which is a
|
|
|
|
|
// friend of this class.
|
|
|
|
|
|
|
|
|
|
void Unref() { |
|
|
|
|
if (gpr_unref(&refs_)) { |
|
|
|
|
Delete(this); |
|
|
|
@ -162,6 +185,8 @@ class InternallyRefCountedWithTracing : public Orphanable { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
void IncrementRefCount() { gpr_ref(&refs_); } |
|
|
|
|
|
|
|
|
|
TraceFlag* trace_flag_ = nullptr; |
|
|
|
|
gpr_refcount refs_; |
|
|
|
|
}; |
|
|
|
|