OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Weak handles provides a way to refer to weak pointers from another | 5 // Weak handles provides a way to refer to weak pointers from another |
6 // thread. This is useful because it is not safe to reference a weak | 6 // thread. This is useful because it is not safe to reference a weak |
7 // pointer from a thread other than the thread on which it was | 7 // pointer from a thread other than the thread on which it was |
8 // created. | 8 // created. |
9 // | 9 // |
10 // Weak handles can be passed across threads, so for example, you can | 10 // Weak handles can be passed across threads, so for example, you can |
(...skipping 26 matching lines...) Expand all Loading... |
37 // SpawnFooIOWorkerOnIOThread(base::MakeWeakHandle(AsWeakPtr())); | 37 // SpawnFooIOWorkerOnIOThread(base::MakeWeakHandle(AsWeakPtr())); |
38 // } | 38 // } |
39 // | 39 // |
40 // /* Will always be called on the correct thread, and only if this | 40 // /* Will always be called on the correct thread, and only if this |
41 // object hasn't been destroyed. */ | 41 // object hasn't been destroyed. */ |
42 // void OnIOStart() { DCHECK(CalledOnValidThread(); ... } | 42 // void OnIOStart() { DCHECK(CalledOnValidThread(); ... } |
43 // void OnIOEvent(IOEvent e) { DCHECK(CalledOnValidThread(); ... } | 43 // void OnIOEvent(IOEvent e) { DCHECK(CalledOnValidThread(); ... } |
44 // void OnIOError(IOError err) { DCHECK(CalledOnValidThread(); ... } | 44 // void OnIOError(IOError err) { DCHECK(CalledOnValidThread(); ... } |
45 // }; | 45 // }; |
46 | 46 |
47 #ifndef SYNC_INTERNAL_API_PUBLIC_UTIL_WEAK_HANDLE_H_ | 47 #ifndef COMPONENTS_SYNC_BASE_WEAK_HANDLE_H_ |
48 #define SYNC_INTERNAL_API_PUBLIC_UTIL_WEAK_HANDLE_H_ | 48 #define COMPONENTS_SYNC_BASE_WEAK_HANDLE_H_ |
49 | 49 |
50 #include <cstddef> | 50 #include <cstddef> |
51 #include <utility> | 51 #include <utility> |
52 | 52 |
53 #include "base/bind.h" | 53 #include "base/bind.h" |
54 #include "base/compiler_specific.h" | 54 #include "base/compiler_specific.h" |
55 #include "base/gtest_prod_util.h" | 55 #include "base/gtest_prod_util.h" |
56 #include "base/location.h" | 56 #include "base/location.h" |
57 #include "base/logging.h" | 57 #include "base/logging.h" |
58 #include "base/macros.h" | 58 #include "base/macros.h" |
59 #include "base/memory/ref_counted.h" | 59 #include "base/memory/ref_counted.h" |
60 #include "base/memory/weak_ptr.h" | 60 #include "base/memory/weak_ptr.h" |
61 #include "base/single_thread_task_runner.h" | 61 #include "base/single_thread_task_runner.h" |
62 #include "sync/base/sync_export.h" | 62 #include "components/sync/base/sync_export.h" |
63 | 63 |
64 namespace tracked_objects { | 64 namespace tracked_objects { |
65 class Location; | 65 class Location; |
66 } // namespace tracked_objects | 66 } // namespace tracked_objects |
67 | 67 |
68 namespace syncer { | 68 namespace syncer { |
69 | 69 |
70 template <typename T> class WeakHandle; | 70 template <typename T> |
| 71 class WeakHandle; |
71 | 72 |
72 namespace internal { | 73 namespace internal { |
73 // These classes are part of the WeakHandle implementation. DO NOT | 74 // These classes are part of the WeakHandle implementation. DO NOT |
74 // USE THESE CLASSES DIRECTLY YOURSELF. | 75 // USE THESE CLASSES DIRECTLY YOURSELF. |
75 | 76 |
76 // Base class for WeakHandleCore<T> to avoid template bloat. Handles | 77 // Base class for WeakHandleCore<T> to avoid template bloat. Handles |
77 // the interaction with the owner thread and its message loop. | 78 // the interaction with the owner thread and its message loop. |
78 class SYNC_EXPORT WeakHandleCoreBase { | 79 class SYNC_EXPORT WeakHandleCoreBase { |
79 public: | 80 public: |
80 // Assumes the current thread is the owner thread. | 81 // Assumes the current thread is the owner thread. |
(...skipping 12 matching lines...) Expand all Loading... |
93 | 94 |
94 private: | 95 private: |
95 // May be used on any thread. | 96 // May be used on any thread. |
96 const scoped_refptr<base::SingleThreadTaskRunner> owner_loop_task_runner_; | 97 const scoped_refptr<base::SingleThreadTaskRunner> owner_loop_task_runner_; |
97 | 98 |
98 DISALLOW_COPY_AND_ASSIGN(WeakHandleCoreBase); | 99 DISALLOW_COPY_AND_ASSIGN(WeakHandleCoreBase); |
99 }; | 100 }; |
100 | 101 |
101 // WeakHandleCore<T> contains all the logic for WeakHandle<T>. | 102 // WeakHandleCore<T> contains all the logic for WeakHandle<T>. |
102 template <typename T> | 103 template <typename T> |
103 class WeakHandleCore | 104 class WeakHandleCore : public WeakHandleCoreBase, |
104 : public WeakHandleCoreBase, | 105 public base::RefCountedThreadSafe<WeakHandleCore<T>> { |
105 public base::RefCountedThreadSafe<WeakHandleCore<T> > { | |
106 public: | 106 public: |
107 // Must be called on |ptr|'s owner thread, which is assumed to be | 107 // Must be called on |ptr|'s owner thread, which is assumed to be |
108 // the current thread. | 108 // the current thread. |
109 explicit WeakHandleCore(const base::WeakPtr<T>& ptr) : ptr_(ptr) {} | 109 explicit WeakHandleCore(const base::WeakPtr<T>& ptr) : ptr_(ptr) {} |
110 | 110 |
111 // Must be called on |ptr_|'s owner thread. | 111 // Must be called on |ptr_|'s owner thread. |
112 base::WeakPtr<T> Get() const { | 112 base::WeakPtr<T> Get() const { |
113 CHECK(IsOnOwnerThread()); | 113 CHECK(IsOnOwnerThread()); |
114 return ptr_; | 114 return ptr_; |
115 } | 115 } |
116 | 116 |
117 // Call(...) may be called on any thread, but all its arguments | 117 // Call(...) may be called on any thread, but all its arguments |
118 // should be safe to be bound and copied across threads. | 118 // should be safe to be bound and copied across threads. |
119 template <typename Method, typename... Args> | 119 template <typename Method, typename... Args> |
120 void Call(const tracked_objects::Location& from_here, | 120 void Call(const tracked_objects::Location& from_here, |
121 Method method, Args&&... args) const { | 121 Method method, |
122 PostToOwnerThread( | 122 Args&&... args) const { |
123 from_here, base::Bind(method, ptr_, std::forward<Args>(args)...)); | 123 PostToOwnerThread(from_here, |
| 124 base::Bind(method, ptr_, std::forward<Args>(args)...)); |
124 } | 125 } |
125 | 126 |
126 private: | 127 private: |
127 friend class base::RefCountedThreadSafe<WeakHandleCore<T> >; | 128 friend class base::RefCountedThreadSafe<WeakHandleCore<T>>; |
128 | 129 |
129 // May be destroyed on any thread. | 130 // May be destroyed on any thread. |
130 ~WeakHandleCore() {} | 131 ~WeakHandleCore() {} |
131 | 132 |
132 // Must be dereferenced only on the owner thread. May be destroyed | 133 // Must be dereferenced only on the owner thread. May be destroyed |
133 // from any thread. | 134 // from any thread. |
134 base::WeakPtr<T> ptr_; | 135 base::WeakPtr<T> ptr_; |
135 | 136 |
136 DISALLOW_COPY_AND_ASSIGN(WeakHandleCore); | 137 DISALLOW_COPY_AND_ASSIGN(WeakHandleCore); |
137 }; | 138 }; |
(...skipping 11 matching lines...) Expand all Loading... |
149 // Creates an initialized WeakHandle from |ptr|. | 150 // Creates an initialized WeakHandle from |ptr|. |
150 explicit WeakHandle(const base::WeakPtr<T>& ptr) | 151 explicit WeakHandle(const base::WeakPtr<T>& ptr) |
151 : core_(new internal::WeakHandleCore<T>(ptr)) {} | 152 : core_(new internal::WeakHandleCore<T>(ptr)) {} |
152 | 153 |
153 // Allow conversion from WeakHandle<U> to WeakHandle<T> if U is | 154 // Allow conversion from WeakHandle<U> to WeakHandle<T> if U is |
154 // convertible to T, but we *must* be on |other|'s owner thread. | 155 // convertible to T, but we *must* be on |other|'s owner thread. |
155 // Note that this doesn't override the regular copy constructor, so | 156 // Note that this doesn't override the regular copy constructor, so |
156 // that one can be called on any thread. | 157 // that one can be called on any thread. |
157 template <typename U> | 158 template <typename U> |
158 WeakHandle(const WeakHandle<U>& other) // NOLINT | 159 WeakHandle(const WeakHandle<U>& other) // NOLINT |
159 : core_( | 160 : core_(other.IsInitialized() |
160 other.IsInitialized() ? | 161 ? new internal::WeakHandleCore<T>(other.Get()) |
161 new internal::WeakHandleCore<T>(other.Get()) : | 162 : NULL) {} |
162 NULL) {} | |
163 | 163 |
164 // Returns true iff this WeakHandle is initialized. Note that being | 164 // Returns true iff this WeakHandle is initialized. Note that being |
165 // initialized isn't a guarantee that the underlying object is still | 165 // initialized isn't a guarantee that the underlying object is still |
166 // alive. | 166 // alive. |
167 bool IsInitialized() const { | 167 bool IsInitialized() const { return core_.get() != NULL; } |
168 return core_.get() != NULL; | |
169 } | |
170 | 168 |
171 // Resets to an uninitialized WeakHandle. | 169 // Resets to an uninitialized WeakHandle. |
172 void Reset() { | 170 void Reset() { core_ = NULL; } |
173 core_ = NULL; | |
174 } | |
175 | 171 |
176 // Must be called only on the underlying object's owner thread. | 172 // Must be called only on the underlying object's owner thread. |
177 base::WeakPtr<T> Get() const { | 173 base::WeakPtr<T> Get() const { |
178 CHECK(IsInitialized()); | 174 CHECK(IsInitialized()); |
179 CHECK(core_->IsOnOwnerThread()); | 175 CHECK(core_->IsOnOwnerThread()); |
180 return core_->Get(); | 176 return core_->Get(); |
181 } | 177 } |
182 | 178 |
183 // Call(...) may be called on any thread, but all its arguments | 179 // Call(...) may be called on any thread, but all its arguments |
184 // should be safe to be bound and copied across threads. | 180 // should be safe to be bound and copied across threads. |
185 template <typename Method, typename... Args> | 181 template <typename Method, typename... Args> |
186 void Call(const tracked_objects::Location& from_here, | 182 void Call(const tracked_objects::Location& from_here, |
187 Method method, Args&&... args) const { | 183 Method method, |
| 184 Args&&... args) const { |
188 CHECK(IsInitialized()); | 185 CHECK(IsInitialized()); |
189 core_->Call(from_here, method, std::forward<Args>(args)...); | 186 core_->Call(from_here, method, std::forward<Args>(args)...); |
190 } | 187 } |
191 | 188 |
192 private: | 189 private: |
193 FRIEND_TEST_ALL_PREFIXES(WeakHandleTest, | 190 FRIEND_TEST_ALL_PREFIXES(WeakHandleTest, TypeConversionConstructor); |
194 TypeConversionConstructor); | 191 FRIEND_TEST_ALL_PREFIXES(WeakHandleTest, TypeConversionConstructorAssignment); |
195 FRIEND_TEST_ALL_PREFIXES(WeakHandleTest, | |
196 TypeConversionConstructorAssignment); | |
197 | 192 |
198 scoped_refptr<internal::WeakHandleCore<T> > core_; | 193 scoped_refptr<internal::WeakHandleCore<T>> core_; |
199 }; | 194 }; |
200 | 195 |
201 // Makes a WeakHandle from a WeakPtr. | 196 // Makes a WeakHandle from a WeakPtr. |
202 template <typename T> | 197 template <typename T> |
203 WeakHandle<T> MakeWeakHandle(const base::WeakPtr<T>& ptr) { | 198 WeakHandle<T> MakeWeakHandle(const base::WeakPtr<T>& ptr) { |
204 return WeakHandle<T>(ptr); | 199 return WeakHandle<T>(ptr); |
205 } | 200 } |
206 | 201 |
207 } // namespace syncer | 202 } // namespace syncer |
208 | 203 |
209 #endif // SYNC_INTERNAL_API_PUBLIC_UTIL_WEAK_HANDLE_H_ | 204 #endif // COMPONENTS_SYNC_BASE_WEAK_HANDLE_H_ |
OLD | NEW |