weak_handle.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright 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 COMPONENTS_SYNC_BASE_WEAK_HANDLE_H_
  5. #define COMPONENTS_SYNC_BASE_WEAK_HANDLE_H_
  6. #include <cstddef>
  7. #include <utility>
  8. #include "base/bind.h"
  9. #include "base/check_op.h"
  10. #include "base/compiler_specific.h"
  11. #include "base/gtest_prod_util.h"
  12. #include "base/location.h"
  13. #include "base/memory/ref_counted.h"
  14. #include "base/memory/weak_ptr.h"
  15. #include "base/task/sequenced_task_runner.h"
  16. // Weak handles provides a way to refer to weak pointers from another sequence.
  17. // This is useful because it is not safe to reference a weak pointer from a
  18. // sequence other than the sequence on which it was created.
  19. //
  20. // Weak handles can be passed across sequences, so for example, you can use them
  21. // to do the "real" work on one thread and get notified on another thread:
  22. //
  23. // class FooIOWorker {
  24. // public:
  25. // FooIOWorker(const WeakHandle<Foo>& foo) : foo_(foo) {}
  26. //
  27. // void OnIOStart() {
  28. // foo_.Call(FROM_HERE, &Foo::OnIOStart);
  29. // }
  30. //
  31. // private:
  32. // const WeakHandle<Foo> foo_;
  33. // };
  34. //
  35. // class Foo : public SupportsWeakPtr<Foo> {
  36. // public:
  37. // Foo() {
  38. // SpawnFooIOWorkerOnIOThread(base::MakeWeakHandle(AsWeakPtr()));
  39. // }
  40. //
  41. // /* Will always be called on the correct sequence, and only if this
  42. // object hasn't been destroyed. */
  43. // void OnIOStart() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); .. }
  44. //
  45. // private:
  46. // SEQUENCE_CHECKER(sequence_checker_);
  47. // };
  48. namespace base {
  49. class Location;
  50. } // namespace base
  51. namespace syncer {
  52. template <typename T>
  53. class WeakHandle;
  54. namespace internal {
  55. // These classes are part of the WeakHandle implementation. DO NOT
  56. // USE THESE CLASSES DIRECTLY YOURSELF.
  57. // Base class for WeakHandleCore<T> to avoid template bloat. Handles
  58. // the interaction with the owner thread and its message loop.
  59. class WeakHandleCoreBase {
  60. public:
  61. // Assumes the current thread is the owner thread.
  62. WeakHandleCoreBase();
  63. WeakHandleCoreBase(const WeakHandleCoreBase&) = delete;
  64. WeakHandleCoreBase& operator=(const WeakHandleCoreBase&) = delete;
  65. // May be called on any thread.
  66. bool IsOnOwnerThread() const;
  67. protected:
  68. // May be destroyed on any thread.
  69. ~WeakHandleCoreBase();
  70. // May be called on any thread.
  71. void PostToOwnerThread(const base::Location& from_here,
  72. base::OnceClosure fn) const;
  73. private:
  74. // May be used on any thread.
  75. const scoped_refptr<base::SequencedTaskRunner> owner_loop_task_runner_;
  76. };
  77. // WeakHandleCore<T> contains all the logic for WeakHandle<T>.
  78. template <typename T>
  79. class WeakHandleCore : public WeakHandleCoreBase,
  80. public base::RefCountedThreadSafe<WeakHandleCore<T>> {
  81. public:
  82. // Must be called on |ptr|'s owner thread, which is assumed to be
  83. // the current thread.
  84. explicit WeakHandleCore(const base::WeakPtr<T>& ptr) : ptr_(ptr) {}
  85. WeakHandleCore(const WeakHandleCore&) = delete;
  86. WeakHandleCore& operator=(const WeakHandleCore&) = delete;
  87. // Must be called on |ptr_|'s owner thread.
  88. base::WeakPtr<T> Get() const {
  89. DCHECK(IsOnOwnerThread());
  90. return ptr_;
  91. }
  92. // Call(...) may be called on any thread, but all its arguments
  93. // should be safe to be bound and copied across threads.
  94. template <typename Method, typename... Args>
  95. void Call(const base::Location& from_here,
  96. Method method,
  97. Args&&... args) const {
  98. PostToOwnerThread(
  99. from_here, base::BindOnce(method, ptr_, std::forward<Args>(args)...));
  100. }
  101. private:
  102. friend class base::RefCountedThreadSafe<WeakHandleCore<T>>;
  103. // May be destroyed on any thread.
  104. ~WeakHandleCore() = default;
  105. // Must be dereferenced only on the owner thread. May be destroyed
  106. // from any thread.
  107. base::WeakPtr<T> ptr_;
  108. };
  109. } // namespace internal
  110. // May be destroyed on any thread.
  111. // Copying and assignment are welcome.
  112. template <typename T>
  113. class WeakHandle {
  114. public:
  115. // Creates an uninitialized WeakHandle.
  116. WeakHandle() = default;
  117. // Creates an initialized WeakHandle from |ptr|.
  118. explicit WeakHandle(const base::WeakPtr<T>& ptr)
  119. : core_(new internal::WeakHandleCore<T>(ptr)) {}
  120. // Allow conversion from WeakHandle<U> to WeakHandle<T> if U is
  121. // convertible to T, but we *must* be on |other|'s owner thread.
  122. // Note that this doesn't override the regular copy constructor, so
  123. // that one can be called on any thread.
  124. template <typename U>
  125. WeakHandle(const WeakHandle<U>& other) // NOLINT
  126. : core_(other.IsInitialized()
  127. ? new internal::WeakHandleCore<T>(other.Get())
  128. : nullptr) {}
  129. // Returns true iff this WeakHandle is initialized. Note that being
  130. // initialized isn't a guarantee that the underlying object is still
  131. // alive.
  132. bool IsInitialized() const { return core_.get() != nullptr; }
  133. // Resets to an uninitialized WeakHandle.
  134. void Reset() { core_ = nullptr; }
  135. // Must be called only on the underlying object's owner thread.
  136. base::WeakPtr<T> Get() const {
  137. DCHECK(IsInitialized());
  138. DCHECK(core_->IsOnOwnerThread());
  139. return core_->Get();
  140. }
  141. // Call(...) may be called on any thread, but all its arguments
  142. // should be safe to be bound and copied across threads.
  143. template <typename Method, typename... Args>
  144. void Call(const base::Location& from_here,
  145. Method method,
  146. Args&&... args) const {
  147. DCHECK(IsInitialized());
  148. core_->Call(from_here, method, std::forward<Args>(args)...);
  149. }
  150. private:
  151. FRIEND_TEST_ALL_PREFIXES(WeakHandleTest, TypeConversionConstructor);
  152. FRIEND_TEST_ALL_PREFIXES(WeakHandleTest, TypeConversionConstructorAssignment);
  153. scoped_refptr<internal::WeakHandleCore<T>> core_;
  154. };
  155. // Makes a WeakHandle from a WeakPtr.
  156. template <typename T>
  157. WeakHandle<T> MakeWeakHandle(const base::WeakPtr<T>& ptr) {
  158. return WeakHandle<T>(ptr);
  159. }
  160. } // namespace syncer
  161. #endif // COMPONENTS_SYNC_BASE_WEAK_HANDLE_H_