Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / deps / grpc / src / core / lib / gprpp / orphanable.h
1 /*
2  *
3  * Copyright 2017 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18
19 #ifndef GRPC_CORE_LIB_GPRPP_ORPHANABLE_H
20 #define GRPC_CORE_LIB_GPRPP_ORPHANABLE_H
21
22 #include <grpc/support/port_platform.h>
23
24 #include <grpc/support/log.h>
25 #include <grpc/support/sync.h>
26
27 #include <cinttypes>
28 #include <memory>
29
30 #include "src/core/lib/debug/trace.h"
31 #include "src/core/lib/gprpp/abstract.h"
32 #include "src/core/lib/gprpp/debug_location.h"
33 #include "src/core/lib/gprpp/memory.h"
34 #include "src/core/lib/gprpp/ref_counted.h"
35 #include "src/core/lib/gprpp/ref_counted_ptr.h"
36
37 namespace grpc_core {
38
39 // A base class for orphanable objects, which have one external owner
40 // but are not necessarily destroyed immediately when the external owner
41 // gives up ownership.  Instead, the owner calls the object's Orphan()
42 // method, and the object then takes responsibility for its own cleanup
43 // and destruction.
44 class Orphanable {
45  public:
46   // Gives up ownership of the object.  The implementation must arrange
47   // to eventually destroy the object without further interaction from the
48   // caller.
49   virtual void Orphan() GRPC_ABSTRACT;
50
51   // Not copyable or movable.
52   Orphanable(const Orphanable&) = delete;
53   Orphanable& operator=(const Orphanable&) = delete;
54
55   GRPC_ABSTRACT_BASE_CLASS
56
57  protected:
58   Orphanable() {}
59   virtual ~Orphanable() {}
60 };
61
62 template <typename T>
63 class OrphanableDelete {
64  public:
65   void operator()(T* p) { p->Orphan(); }
66 };
67
68 template <typename T, typename Deleter = OrphanableDelete<T>>
69 using OrphanablePtr = std::unique_ptr<T, Deleter>;
70
71 template <typename T, typename... Args>
72 inline OrphanablePtr<T> MakeOrphanable(Args&&... args) {
73   return OrphanablePtr<T>(New<T>(std::forward<Args>(args)...));
74 }
75
76 // A type of Orphanable with internal ref-counting.
77 template <typename Child>
78 class InternallyRefCounted : public Orphanable {
79  public:
80   // Not copyable nor movable.
81   InternallyRefCounted(const InternallyRefCounted&) = delete;
82   InternallyRefCounted& operator=(const InternallyRefCounted&) = delete;
83
84   GRPC_ABSTRACT_BASE_CLASS
85
86  protected:
87   GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
88
89   // Allow RefCountedPtr<> to access Unref() and IncrementRefCount().
90   template <typename T>
91   friend class RefCountedPtr;
92
93   // TraceFlagT is defined to accept both DebugOnlyTraceFlag and TraceFlag.
94   // Note: RefCount tracing is only enabled on debug builds, even when a
95   //       TraceFlag is used.
96   template <typename TraceFlagT = TraceFlag>
97   explicit InternallyRefCounted(TraceFlagT* trace_flag = nullptr,
98                                 intptr_t initial_refcount = 1)
99       : refs_(initial_refcount, trace_flag) {}
100   virtual ~InternallyRefCounted() = default;
101
102   RefCountedPtr<Child> Ref() GRPC_MUST_USE_RESULT {
103     IncrementRefCount();
104     return RefCountedPtr<Child>(static_cast<Child*>(this));
105   }
106   RefCountedPtr<Child> Ref(const DebugLocation& location,
107                            const char* reason) GRPC_MUST_USE_RESULT {
108     IncrementRefCount(location, reason);
109     return RefCountedPtr<Child>(static_cast<Child*>(this));
110   }
111
112   void Unref() {
113     if (GPR_UNLIKELY(refs_.Unref())) {
114       Delete(static_cast<Child*>(this));
115     }
116   }
117   void Unref(const DebugLocation& location, const char* reason) {
118     if (GPR_UNLIKELY(refs_.Unref(location, reason))) {
119       Delete(static_cast<Child*>(this));
120     }
121   }
122
123  private:
124   void IncrementRefCount() { refs_.Ref(); }
125   void IncrementRefCount(const DebugLocation& location, const char* reason) {
126     refs_.Ref(location, reason);
127   }
128
129   grpc_core::RefCount refs_;
130 };
131
132 }  // namespace grpc_core
133
134 #endif /* GRPC_CORE_LIB_GPRPP_ORPHANABLE_H */