proxygen
DelayedDestructionBase.h
Go to the documentation of this file.
1 /*
2  * Copyright 2015-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <assert.h>
20 #include <cstddef>
21 #include <cstdint>
22 #include <functional>
23 #include <memory>
24 #include <type_traits>
25 #include <utility>
26 
27 #include <boost/noncopyable.hpp>
28 #include <glog/logging.h>
29 
30 namespace folly {
31 
49 class DelayedDestructionBase : private boost::noncopyable {
50  public:
51  virtual ~DelayedDestructionBase() = default;
52 
63  public:
65  if (dd_ != nullptr) {
66  ++dd_->guardCount_;
67  assert(dd_->guardCount_ > 0); // check for wrapping
68  }
69  }
70 
72 
74  : dd_(std::exchange(dg.dd_, nullptr)) {}
75 
77  std::swap(dd_, dg.dd_);
78  return *this;
79  }
80 
82  *this = DestructorGuard(dd);
83  return *this;
84  }
85 
87  if (dd_ != nullptr) {
88  assert(dd_->guardCount_ > 0);
89  --dd_->guardCount_;
90  if (dd_->guardCount_ == 0) {
91  dd_->onDelayedDestroy(true);
92  }
93  }
94  }
95 
96  DelayedDestructionBase* get() const {
97  return dd_;
98  }
99 
100  explicit operator bool() const {
101  return dd_ != nullptr;
102  }
103 
104  private:
106  };
107 
113  template <typename AliasType>
114  class IntrusivePtr : private DestructorGuard {
115  template <typename CopyAliasType>
116  friend class IntrusivePtr;
117 
118  public:
119  template <typename... Args>
120  static IntrusivePtr<AliasType> make(Args&&... args) {
121  return {new AliasType(std::forward<Args>(args)...)};
122  }
123 
124  IntrusivePtr() = default;
125  IntrusivePtr(const IntrusivePtr&) = default;
126  IntrusivePtr(IntrusivePtr&&) noexcept = default;
127 
128  template <
129  typename CopyAliasType,
130  typename = typename std::enable_if<
133  : DestructorGuard(copy) {}
134 
135  template <
136  typename CopyAliasType,
137  typename = typename std::enable_if<
140  : DestructorGuard(std::move(copy)) {}
141 
142  explicit IntrusivePtr(AliasType* dd) : DestructorGuard(dd) {}
143 
144  // Copying from a unique_ptr is safe because if the upcast to
145  // DelayedDestructionBase works, then the instance is already using
146  // intrusive ref-counting.
147  template <
148  typename CopyAliasType,
149  typename Deleter,
150  typename = typename std::enable_if<
152  explicit IntrusivePtr(const std::unique_ptr<CopyAliasType, Deleter>& copy)
153  : DestructorGuard(copy.get()) {}
154 
155  IntrusivePtr& operator=(const IntrusivePtr&) = default;
157 
158  template <
159  typename CopyAliasType,
160  typename = typename std::enable_if<
164  return *this;
165  }
166 
167  IntrusivePtr& operator=(AliasType* dd) {
169  return *this;
170  }
171 
172  void reset(AliasType* dd = nullptr) {
173  *this = dd;
174  }
175 
176  AliasType* get() const {
177  return static_cast<AliasType*>(DestructorGuard::get());
178  }
179 
180  AliasType& operator*() const {
181  return *get();
182  }
183 
184  AliasType* operator->() const {
185  return get();
186  }
187 
188  explicit operator bool() const {
189  return DestructorGuard::operator bool();
190  }
191  };
192 
193  protected:
195 
203  return guardCount_;
204  }
205 
215  virtual void onDelayedDestroy(bool delayed) = 0;
216 
217  private:
228 };
229 
230 inline bool operator==(
233  return left.get() == right.get();
234 }
235 inline bool operator!=(
238  return left.get() != right.get();
239 }
240 inline bool operator==(
242  std::nullptr_t) {
243  return left.get() == nullptr;
244 }
245 inline bool operator==(
246  std::nullptr_t,
248  return nullptr == right.get();
249 }
250 inline bool operator!=(
252  std::nullptr_t) {
253  return left.get() != nullptr;
254 }
255 inline bool operator!=(
256  std::nullptr_t,
258  return nullptr != right.get();
259 }
260 
261 template <typename LeftAliasType, typename RightAliasType>
262 inline bool operator==(
265  return left.get() == right.get();
266 }
267 template <typename LeftAliasType, typename RightAliasType>
268 inline bool operator!=(
271  return left.get() != right.get();
272 }
273 template <typename LeftAliasType>
274 inline bool operator==(
276  std::nullptr_t) {
277  return left.get() == nullptr;
278 }
279 template <typename RightAliasType>
280 inline bool operator==(
281  std::nullptr_t,
283  return nullptr == right.get();
284 }
285 template <typename LeftAliasType>
286 inline bool operator!=(
288  std::nullptr_t) {
289  return left.get() != nullptr;
290 }
291 template <typename RightAliasType>
292 inline bool operator!=(
293  std::nullptr_t,
295  return nullptr != right.get();
296 }
297 } // namespace folly
IntrusivePtr(const IntrusivePtr< CopyAliasType > &copy)
static IntrusivePtr< AliasType > make(Args &&...args)
IntrusivePtr(const std::unique_ptr< CopyAliasType, Deleter > &copy)
PskType type
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
STL namespace.
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
requires E e noexcept(noexcept(s.error(std::move(e))))
DestructorGuard & operator=(DestructorGuard dg) noexcept
IntrusivePtr & operator=(IntrusivePtr< CopyAliasType > copy) noexcept
bool operator!=(const Unexpected< Error > &lhs, const Unexpected< Error > &rhs)
Definition: Expected.h:766
constexpr std::decay< T >::type copy(T &&value) noexcept(noexcept(typename std::decay< T >::type(std::forward< T >(value))))
Definition: Utility.h:72
virtual ~DelayedDestructionBase()=default
static const char *const value
Definition: Conv.cpp:50
DestructorGuard & operator=(DelayedDestructionBase *dd)
T exchange(T &obj, U &&new_value)
Definition: Utility.h:120
IntrusivePtr(IntrusivePtr< CopyAliasType > &&copy)
bool operator==(const Unexpected< Error > &lhs, const Unexpected< Error > &rhs)
Definition: Expected.h:758
void swap(SwapTrackingAlloc< T > &, SwapTrackingAlloc< T > &)
Definition: F14TestUtil.h:414
virtual void onDelayedDestroy(bool delayed)=0