ref_counted.h 14 KB

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