|
|
|
@ -219,7 +219,7 @@ class NonPolymorphicRefCount { |
|
|
|
|
// Default behavior: Delete the object.
|
|
|
|
|
struct UnrefDelete { |
|
|
|
|
template <typename T> |
|
|
|
|
void operator()(T* p) { |
|
|
|
|
void operator()(T* p) const { |
|
|
|
|
delete p; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
@ -231,7 +231,7 @@ struct UnrefDelete { |
|
|
|
|
// later by identifying entries for which RefIfNonZero() returns null.
|
|
|
|
|
struct UnrefNoDelete { |
|
|
|
|
template <typename T> |
|
|
|
|
void operator()(T* /*p*/) {} |
|
|
|
|
void operator()(T* /*p*/) const {} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Call the object's dtor but do not delete it. This is useful for cases
|
|
|
|
@ -239,7 +239,7 @@ struct UnrefNoDelete { |
|
|
|
|
// arena).
|
|
|
|
|
struct UnrefCallDtor { |
|
|
|
|
template <typename T> |
|
|
|
|
void operator()(T* p) { |
|
|
|
|
void operator()(T* p) const { |
|
|
|
|
p->~T(); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
@ -279,32 +279,44 @@ class RefCounted : public Impl { |
|
|
|
|
// Note: Depending on the Impl used, this dtor can be implicitly virtual.
|
|
|
|
|
~RefCounted() = default; |
|
|
|
|
|
|
|
|
|
// Ref() for mutable types.
|
|
|
|
|
GRPC_MUST_USE_RESULT RefCountedPtr<Child> Ref() { |
|
|
|
|
IncrementRefCount(); |
|
|
|
|
return RefCountedPtr<Child>(static_cast<Child*>(this)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
GRPC_MUST_USE_RESULT RefCountedPtr<Child> Ref(const DebugLocation& location, |
|
|
|
|
const char* reason) { |
|
|
|
|
IncrementRefCount(location, reason); |
|
|
|
|
return RefCountedPtr<Child>(static_cast<Child*>(this)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Ref() for const types.
|
|
|
|
|
GRPC_MUST_USE_RESULT RefCountedPtr<const Child> Ref() const { |
|
|
|
|
IncrementRefCount(); |
|
|
|
|
return RefCountedPtr<const Child>(static_cast<const Child*>(this)); |
|
|
|
|
} |
|
|
|
|
GRPC_MUST_USE_RESULT RefCountedPtr<const Child> Ref( |
|
|
|
|
const DebugLocation& location, const char* reason) const { |
|
|
|
|
IncrementRefCount(location, reason); |
|
|
|
|
return RefCountedPtr<const Child>(static_cast<const Child*>(this)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO(roth): Once all of our code is converted to C++ and can use
|
|
|
|
|
// RefCountedPtr<> instead of manual ref-counting, make this method
|
|
|
|
|
// private, since it will only be used by RefCountedPtr<>, which is a
|
|
|
|
|
// friend of this class.
|
|
|
|
|
void Unref() { |
|
|
|
|
void Unref() const { |
|
|
|
|
if (GPR_UNLIKELY(refs_.Unref())) { |
|
|
|
|
unref_behavior_(static_cast<Child*>(this)); |
|
|
|
|
unref_behavior_(static_cast<const Child*>(this)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
void Unref(const DebugLocation& location, const char* reason) { |
|
|
|
|
void Unref(const DebugLocation& location, const char* reason) const { |
|
|
|
|
if (GPR_UNLIKELY(refs_.Unref(location, reason))) { |
|
|
|
|
unref_behavior_(static_cast<Child*>(this)); |
|
|
|
|
unref_behavior_(static_cast<const Child*>(this)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// RefIfNonZero() for mutable types.
|
|
|
|
|
GRPC_MUST_USE_RESULT RefCountedPtr<Child> RefIfNonZero() { |
|
|
|
|
return RefCountedPtr<Child>(refs_.RefIfNonZero() ? static_cast<Child*>(this) |
|
|
|
|
: nullptr); |
|
|
|
@ -316,6 +328,18 @@ class RefCounted : public Impl { |
|
|
|
|
: nullptr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// RefIfNonZero() for const types.
|
|
|
|
|
GRPC_MUST_USE_RESULT RefCountedPtr<const Child> RefIfNonZero() const { |
|
|
|
|
return RefCountedPtr<const Child>( |
|
|
|
|
refs_.RefIfNonZero() ? static_cast<const Child*>(this) : nullptr); |
|
|
|
|
} |
|
|
|
|
GRPC_MUST_USE_RESULT RefCountedPtr<const Child> RefIfNonZero( |
|
|
|
|
const DebugLocation& location, const char* reason) const { |
|
|
|
|
return RefCountedPtr<const Child>(refs_.RefIfNonZero(location, reason) |
|
|
|
|
? static_cast<const Child*>(this) |
|
|
|
|
: nullptr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Not copyable nor movable.
|
|
|
|
|
RefCounted(const RefCounted&) = delete; |
|
|
|
|
RefCounted& operator=(const RefCounted&) = delete; |
|
|
|
@ -336,12 +360,13 @@ class RefCounted : public Impl { |
|
|
|
|
template <typename T> |
|
|
|
|
friend class RefCountedPtr; |
|
|
|
|
|
|
|
|
|
void IncrementRefCount() { refs_.Ref(); } |
|
|
|
|
void IncrementRefCount(const DebugLocation& location, const char* reason) { |
|
|
|
|
void IncrementRefCount() const { refs_.Ref(); } |
|
|
|
|
void IncrementRefCount(const DebugLocation& location, |
|
|
|
|
const char* reason) const { |
|
|
|
|
refs_.Ref(location, reason); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
RefCount refs_; |
|
|
|
|
mutable RefCount refs_; |
|
|
|
|
GPR_NO_UNIQUE_ADDRESS UnrefBehavior unref_behavior_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|