|  | @@ -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_;
 | 
	
		
			
				|  |  |  };
 |