ref_counted.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_MEMORY_REF_COUNTED_H_
  5. #define BASE_MEMORY_REF_COUNTED_H_
  6. #include <stddef.h>
  7. #include <utility>
  8. #include "base/atomic_ref_count.h"
  9. #include "base/base_export.h"
  10. #include "base/check.h"
  11. #include "base/check_op.h"
  12. #include "base/compiler_specific.h"
  13. #include "base/dcheck_is_on.h"
  14. #include "base/gtest_prod_util.h"
  15. #include "base/memory/scoped_refptr.h"
  16. #include "base/sequence_checker.h"
  17. #include "base/template_util.h"
  18. #include "base/threading/thread_collision_warner.h"
  19. #include "build/build_config.h"
  20. #include "third_party/abseil-cpp/absl/utility/utility.h"
  21. namespace base {
  22. namespace subtle {
  23. class BASE_EXPORT RefCountedBase {
  24. public:
  25. RefCountedBase(const RefCountedBase&) = delete;
  26. RefCountedBase& operator=(const RefCountedBase&) = delete;
  27. bool HasOneRef() const { return ref_count_ == 1; }
  28. bool HasAtLeastOneRef() const { return ref_count_ >= 1; }
  29. protected:
  30. explicit RefCountedBase(StartRefCountFromZeroTag) {
  31. #if DCHECK_IS_ON()
  32. sequence_checker_.DetachFromSequence();
  33. #endif
  34. }
  35. explicit RefCountedBase(StartRefCountFromOneTag) : ref_count_(1) {
  36. #if DCHECK_IS_ON()
  37. needs_adopt_ref_ = true;
  38. sequence_checker_.DetachFromSequence();
  39. #endif
  40. }
  41. ~RefCountedBase() {
  42. #if DCHECK_IS_ON()
  43. // RefCounted object deleted without calling Release()
  44. DCHECK(in_dtor_);
  45. #endif
  46. }
  47. void AddRef() const {
  48. #if DCHECK_IS_ON()
  49. DCHECK(!in_dtor_);
  50. // This RefCounted object is created with non-zero reference count.
  51. // The first reference to such a object has to be made by AdoptRef or
  52. // MakeRefCounted.
  53. DCHECK(!needs_adopt_ref_);
  54. if (ref_count_ >= 1) {
  55. DCHECK(CalledOnValidSequence());
  56. }
  57. #endif
  58. AddRefImpl();
  59. }
  60. // Returns true if the object should self-delete.
  61. bool Release() const {
  62. ReleaseImpl();
  63. #if DCHECK_IS_ON()
  64. DCHECK(!in_dtor_);
  65. if (ref_count_ == 0)
  66. in_dtor_ = true;
  67. if (ref_count_ >= 1)
  68. DCHECK(CalledOnValidSequence());
  69. if (ref_count_ == 1)
  70. sequence_checker_.DetachFromSequence();
  71. #endif
  72. return ref_count_ == 0;
  73. }
  74. // Returns true if it is safe to read or write the object, from a thread
  75. // safety standpoint. Should be DCHECK'd from the methods of RefCounted
  76. // classes if there is a danger of objects being shared across threads.
  77. //
  78. // This produces fewer false positives than adding a separate SequenceChecker
  79. // into the subclass, because it automatically detaches from the sequence when
  80. // the reference count is 1 (and never fails if there is only one reference).
  81. //
  82. // This means unlike a separate SequenceChecker, it will permit a singly
  83. // referenced object to be passed between threads (not holding a reference on
  84. // the sending thread), but will trap if the sending thread holds onto a
  85. // reference, or if the object is accessed from multiple threads
  86. // simultaneously.
  87. bool IsOnValidSequence() const {
  88. #if DCHECK_IS_ON()
  89. return ref_count_ <= 1 || CalledOnValidSequence();
  90. #else
  91. return true;
  92. #endif
  93. }
  94. private:
  95. template <typename U>
  96. friend scoped_refptr<U> base::AdoptRef(U*);
  97. FRIEND_TEST_ALL_PREFIXES(RefCountedDeathTest, TestOverflowCheck);
  98. void Adopted() const {
  99. #if DCHECK_IS_ON()
  100. DCHECK(needs_adopt_ref_);
  101. needs_adopt_ref_ = false;
  102. #endif
  103. }
  104. #if defined(ARCH_CPU_64_BITS)
  105. void AddRefImpl() const;
  106. void ReleaseImpl() const;
  107. #else
  108. void AddRefImpl() const { ++ref_count_; }
  109. void ReleaseImpl() const { --ref_count_; }
  110. #endif
  111. #if DCHECK_IS_ON()
  112. bool CalledOnValidSequence() const;
  113. #endif
  114. mutable uint32_t ref_count_ = 0;
  115. static_assert(std::is_unsigned<decltype(ref_count_)>::value,
  116. "ref_count_ must be an unsigned type.");
  117. #if DCHECK_IS_ON()
  118. mutable bool needs_adopt_ref_ = false;
  119. mutable bool in_dtor_ = false;
  120. mutable SequenceChecker sequence_checker_;
  121. #endif
  122. DFAKE_MUTEX(add_release_);
  123. };
  124. class BASE_EXPORT RefCountedThreadSafeBase {
  125. public:
  126. RefCountedThreadSafeBase(const RefCountedThreadSafeBase&) = delete;
  127. RefCountedThreadSafeBase& operator=(const RefCountedThreadSafeBase&) = delete;
  128. bool HasOneRef() const;
  129. bool HasAtLeastOneRef() const;
  130. protected:
  131. explicit constexpr RefCountedThreadSafeBase(StartRefCountFromZeroTag) {}
  132. explicit constexpr RefCountedThreadSafeBase(StartRefCountFromOneTag)
  133. : ref_count_(1) {
  134. #if DCHECK_IS_ON()
  135. needs_adopt_ref_ = true;
  136. #endif
  137. }
  138. #if DCHECK_IS_ON()
  139. ~RefCountedThreadSafeBase();
  140. #else
  141. ~RefCountedThreadSafeBase() = default;
  142. #endif
  143. // Release and AddRef are suitable for inlining on X86 because they generate
  144. // very small code sequences.
  145. //
  146. // ARM64 devices supporting ARMv8.1-A atomic instructions generate very little
  147. // code, e.g. fetch_add() with acquire ordering is a single instruction (ldadd),
  148. // vs LL/SC in previous ARM architectures. Inline it there as well.
  149. //
  150. // On other platforms (e.g. ARM), it causes a size regression and is probably
  151. // not worth it.
  152. #if defined(ARCH_CPU_X86_FAMILY) || defined(__ARM_FEATURE_ATOMICS)
  153. // Returns true if the object should self-delete.
  154. bool Release() const { return ReleaseImpl(); }
  155. void AddRef() const { AddRefImpl(); }
  156. void AddRefWithCheck() const { AddRefWithCheckImpl(); }
  157. #else
  158. // Returns true if the object should self-delete.
  159. bool Release() const;
  160. void AddRef() const;
  161. void AddRefWithCheck() const;
  162. #endif
  163. private:
  164. template <typename U>
  165. friend scoped_refptr<U> base::AdoptRef(U*);
  166. void Adopted() const {
  167. #if DCHECK_IS_ON()
  168. DCHECK(needs_adopt_ref_);
  169. needs_adopt_ref_ = false;
  170. #endif
  171. }
  172. ALWAYS_INLINE void AddRefImpl() const {
  173. #if DCHECK_IS_ON()
  174. DCHECK(!in_dtor_);
  175. // This RefCounted object is created with non-zero reference count.
  176. // The first reference to such a object has to be made by AdoptRef or
  177. // MakeRefCounted.
  178. DCHECK(!needs_adopt_ref_);
  179. #endif
  180. ref_count_.Increment();
  181. }
  182. ALWAYS_INLINE void AddRefWithCheckImpl() const {
  183. #if DCHECK_IS_ON()
  184. DCHECK(!in_dtor_);
  185. // This RefCounted object is created with non-zero reference count.
  186. // The first reference to such a object has to be made by AdoptRef or
  187. // MakeRefCounted.
  188. DCHECK(!needs_adopt_ref_);
  189. #endif
  190. CHECK_GT(ref_count_.Increment(), 0);
  191. }
  192. ALWAYS_INLINE bool ReleaseImpl() const {
  193. #if DCHECK_IS_ON()
  194. DCHECK(!in_dtor_);
  195. DCHECK(!ref_count_.IsZero());
  196. #endif
  197. if (!ref_count_.Decrement()) {
  198. #if DCHECK_IS_ON()
  199. in_dtor_ = true;
  200. #endif
  201. return true;
  202. }
  203. return false;
  204. }
  205. mutable AtomicRefCount ref_count_{0};
  206. #if DCHECK_IS_ON()
  207. mutable bool needs_adopt_ref_ = false;
  208. mutable bool in_dtor_ = false;
  209. #endif
  210. };
  211. } // namespace subtle
  212. // ScopedAllowCrossThreadRefCountAccess disables the check documented on
  213. // RefCounted below for rare pre-existing use cases where thread-safety was
  214. // guaranteed through other means (e.g. explicit sequencing of calls across
  215. // execution sequences when bouncing between threads in order). New callers
  216. // should refrain from using this (callsites handling thread-safety through
  217. // locks should use RefCountedThreadSafe per the overhead of its atomics being
  218. // negligible compared to locks anyways and callsites doing explicit sequencing
  219. // should properly std::move() the ref to avoid hitting this check).
  220. // TODO(tzik): Cleanup existing use cases and remove
  221. // ScopedAllowCrossThreadRefCountAccess.
  222. class BASE_EXPORT ScopedAllowCrossThreadRefCountAccess final {
  223. public:
  224. #if DCHECK_IS_ON()
  225. ScopedAllowCrossThreadRefCountAccess();
  226. ~ScopedAllowCrossThreadRefCountAccess();
  227. #else
  228. ScopedAllowCrossThreadRefCountAccess() {}
  229. ~ScopedAllowCrossThreadRefCountAccess() {}
  230. #endif
  231. };
  232. //
  233. // A base class for reference counted classes. Otherwise, known as a cheap
  234. // knock-off of WebKit's RefCounted<T> class. To use this, just extend your
  235. // class from it like so:
  236. //
  237. // class MyFoo : public base::RefCounted<MyFoo> {
  238. // ...
  239. // private:
  240. // friend class base::RefCounted<MyFoo>;
  241. // ~MyFoo();
  242. // };
  243. //
  244. // Usage Notes:
  245. // 1. You should always make your destructor non-public, to avoid any code
  246. // deleting the object accidentally while there are references to it.
  247. // 2. You should always make the ref-counted base class a friend of your class,
  248. // so that it can access the destructor.
  249. //
  250. // The ref count manipulation to RefCounted is NOT thread safe and has DCHECKs
  251. // to trap unsafe cross thread usage. A subclass instance of RefCounted can be
  252. // passed to another execution sequence only when its ref count is 1. If the ref
  253. // count is more than 1, the RefCounted class verifies the ref updates are made
  254. // on the same execution sequence as the previous ones. The subclass can also
  255. // manually call IsOnValidSequence to trap other non-thread-safe accesses; see
  256. // the documentation for that method.
  257. //
  258. //
  259. // The reference count starts from zero by default, and we intended to migrate
  260. // to start-from-one ref count. Put REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE() to
  261. // the ref counted class to opt-in.
  262. //
  263. // If an object has start-from-one ref count, the first scoped_refptr need to be
  264. // created by base::AdoptRef() or base::MakeRefCounted(). We can use
  265. // base::MakeRefCounted() to create create both type of ref counted object.
  266. //
  267. // The motivations to use start-from-one ref count are:
  268. // - Start-from-one ref count doesn't need the ref count increment for the
  269. // first reference.
  270. // - It can detect an invalid object acquisition for a being-deleted object
  271. // that has zero ref count. That tends to happen on custom deleter that
  272. // delays the deletion.
  273. // TODO(tzik): Implement invalid acquisition detection.
  274. // - Behavior parity to Blink's WTF::RefCounted, whose count starts from one.
  275. // And start-from-one ref count is a step to merge WTF::RefCounted into
  276. // base::RefCounted.
  277. //
  278. #define REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE() \
  279. static constexpr ::base::subtle::StartRefCountFromOneTag \
  280. kRefCountPreference = ::base::subtle::kStartRefCountFromOneTag
  281. template <class T, typename Traits>
  282. class RefCounted;
  283. template <typename T>
  284. struct DefaultRefCountedTraits {
  285. static void Destruct(const T* x) {
  286. RefCounted<T, DefaultRefCountedTraits>::DeleteInternal(x);
  287. }
  288. };
  289. template <class T, typename Traits = DefaultRefCountedTraits<T>>
  290. class RefCounted : public subtle::RefCountedBase {
  291. public:
  292. static constexpr subtle::StartRefCountFromZeroTag kRefCountPreference =
  293. subtle::kStartRefCountFromZeroTag;
  294. RefCounted() : subtle::RefCountedBase(T::kRefCountPreference) {}
  295. RefCounted(const RefCounted&) = delete;
  296. RefCounted& operator=(const RefCounted&) = delete;
  297. void AddRef() const {
  298. subtle::RefCountedBase::AddRef();
  299. }
  300. void Release() const {
  301. if (subtle::RefCountedBase::Release()) {
  302. // Prune the code paths which the static analyzer may take to simulate
  303. // object destruction. Use-after-free errors aren't possible given the
  304. // lifetime guarantees of the refcounting system.
  305. ANALYZER_SKIP_THIS_PATH();
  306. Traits::Destruct(static_cast<const T*>(this));
  307. }
  308. }
  309. protected:
  310. ~RefCounted() = default;
  311. private:
  312. friend struct DefaultRefCountedTraits<T>;
  313. template <typename U>
  314. static void DeleteInternal(const U* x) {
  315. delete x;
  316. }
  317. };
  318. // Forward declaration.
  319. template <class T, typename Traits> class RefCountedThreadSafe;
  320. // Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref
  321. // count reaches 0. Overload to delete it on a different thread etc.
  322. template<typename T>
  323. struct DefaultRefCountedThreadSafeTraits {
  324. static void Destruct(const T* x) {
  325. // Delete through RefCountedThreadSafe to make child classes only need to be
  326. // friend with RefCountedThreadSafe instead of this struct, which is an
  327. // implementation detail.
  328. RefCountedThreadSafe<T,
  329. DefaultRefCountedThreadSafeTraits>::DeleteInternal(x);
  330. }
  331. };
  332. //
  333. // A thread-safe variant of RefCounted<T>
  334. //
  335. // class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
  336. // ...
  337. // };
  338. //
  339. // If you're using the default trait, then you should add compile time
  340. // asserts that no one else is deleting your object. i.e.
  341. // private:
  342. // friend class base::RefCountedThreadSafe<MyFoo>;
  343. // ~MyFoo();
  344. //
  345. // We can use REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE() with RefCountedThreadSafe
  346. // too. See the comment above the RefCounted definition for details.
  347. template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> >
  348. class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
  349. public:
  350. static constexpr subtle::StartRefCountFromZeroTag kRefCountPreference =
  351. subtle::kStartRefCountFromZeroTag;
  352. explicit RefCountedThreadSafe()
  353. : subtle::RefCountedThreadSafeBase(T::kRefCountPreference) {}
  354. RefCountedThreadSafe(const RefCountedThreadSafe&) = delete;
  355. RefCountedThreadSafe& operator=(const RefCountedThreadSafe&) = delete;
  356. void AddRef() const { AddRefImpl(T::kRefCountPreference); }
  357. void Release() const {
  358. if (subtle::RefCountedThreadSafeBase::Release()) {
  359. ANALYZER_SKIP_THIS_PATH();
  360. Traits::Destruct(static_cast<const T*>(this));
  361. }
  362. }
  363. protected:
  364. ~RefCountedThreadSafe() = default;
  365. private:
  366. friend struct DefaultRefCountedThreadSafeTraits<T>;
  367. template <typename U>
  368. static void DeleteInternal(const U* x) {
  369. delete x;
  370. }
  371. void AddRefImpl(subtle::StartRefCountFromZeroTag) const {
  372. subtle::RefCountedThreadSafeBase::AddRef();
  373. }
  374. void AddRefImpl(subtle::StartRefCountFromOneTag) const {
  375. subtle::RefCountedThreadSafeBase::AddRefWithCheck();
  376. }
  377. };
  378. //
  379. // A thread-safe wrapper for some piece of data so we can place other
  380. // things in scoped_refptrs<>.
  381. //
  382. template<typename T>
  383. class RefCountedData
  384. : public base::RefCountedThreadSafe< base::RefCountedData<T> > {
  385. public:
  386. RefCountedData() : data() {}
  387. RefCountedData(const T& in_value) : data(in_value) {}
  388. RefCountedData(T&& in_value) : data(std::move(in_value)) {}
  389. template <typename... Args>
  390. explicit RefCountedData(absl::in_place_t, Args&&... args)
  391. : data(std::forward<Args>(args)...) {}
  392. T data;
  393. private:
  394. friend class base::RefCountedThreadSafe<base::RefCountedData<T> >;
  395. ~RefCountedData() = default;
  396. };
  397. template <typename T>
  398. bool operator==(const RefCountedData<T>& lhs, const RefCountedData<T>& rhs) {
  399. return lhs.data == rhs.data;
  400. }
  401. template <typename T>
  402. bool operator!=(const RefCountedData<T>& lhs, const RefCountedData<T>& rhs) {
  403. return !(lhs == rhs);
  404. }
  405. } // namespace base
  406. #endif // BASE_MEMORY_REF_COUNTED_H_