Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(119)

Side by Side Diff: chrome/browser/sync/util/weak_handle.h

Issue 9699057: [Sync] Move 'sync' target to sync/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address Tim's comments Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/sync/util/user_settings.h ('k') | chrome/browser/sync/util/weak_handle.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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
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
7 // pointer from a thread other than the thread on which it was
8 // created.
9 //
10 // Weak handles can be passed across threads, so for example, you can
11 // use them to do the "real" work on one thread and get notified on
12 // another thread:
13 //
14 // class FooIOWorker {
15 // public:
16 // FooIOWorker(const WeakHandle<Foo>& foo) : foo_(foo) {}
17 //
18 // void OnIOStart() {
19 // foo_.Call(FROM_HERE, &Foo::OnIOStart);
20 // }
21 //
22 // void OnIOEvent(IOEvent e) {
23 // foo_.Call(FROM_HERE, &Foo::OnIOEvent, e);
24 // }
25 //
26 // void OnIOError(IOError err) {
27 // foo_.Call(FROM_HERE, &Foo::OnIOError, err);
28 // }
29 //
30 // private:
31 // const WeakHandle<Foo> foo_;
32 // };
33 //
34 // class Foo : public SupportsWeakPtr<Foo>, public NonThreadSafe {
35 // public:
36 // Foo() {
37 // SpawnFooIOWorkerOnIOThread(base::MakeWeakHandle(AsWeakPtr()));
38 // }
39 //
40 // /* Will always be called on the correct thread, and only if this
41 // object hasn't been destroyed. */
42 // void OnIOStart() { DCHECK(CalledOnValidThread(); ... }
43 // void OnIOEvent(IOEvent e) { DCHECK(CalledOnValidThread(); ... }
44 // void OnIOError(IOError err) { DCHECK(CalledOnValidThread(); ... }
45 // };
46
47 #ifndef CHROME_BROWSER_SYNC_UTIL_WEAK_HANDLE_H_
48 #define CHROME_BROWSER_SYNC_UTIL_WEAK_HANDLE_H_
49 #pragma once
50
51 #include <cstddef>
52
53 #include "base/basictypes.h"
54 #include "base/bind.h"
55 #include "base/callback_forward.h"
56 #include "base/compiler_specific.h"
57 #include "base/gtest_prod_util.h"
58 #include "base/location.h"
59 #include "base/logging.h"
60 #include "base/memory/ref_counted.h"
61 #include "base/memory/weak_ptr.h"
62
63 namespace base {
64 class MessageLoopProxy;
65 } // namespace base
66
67 namespace tracked_objects {
68 class Location;
69 } // namespace tracked_objects
70
71 namespace browser_sync {
72
73 template <typename T> class WeakHandle;
74
75 namespace internal {
76 // These classes are part of the WeakHandle implementation. DO NOT
77 // USE THESE CLASSES DIRECTLY YOURSELF.
78
79 // Adapted from base/callback_internal.h.
80
81 template <typename T>
82 struct ParamTraits {
83 typedef const T& ForwardType;
84 };
85
86 template <typename T>
87 struct ParamTraits<T&> {
88 typedef T& ForwardType;
89 };
90
91 template <typename T, size_t n>
92 struct ParamTraits<T[n]> {
93 typedef const T* ForwardType;
94 };
95
96 template <typename T>
97 struct ParamTraits<T[]> {
98 typedef const T* ForwardType;
99 };
100
101 // Base class for WeakHandleCore<T> to avoid template bloat. Handles
102 // the interaction with the owner thread and its message loop.
103 class WeakHandleCoreBase {
104 public:
105 // Assumes the current thread is the owner thread.
106 WeakHandleCoreBase();
107
108 // May be called on any thread.
109 bool IsOnOwnerThread() const;
110
111 protected:
112 // May be destroyed on any thread.
113 ~WeakHandleCoreBase();
114
115 // May be called on any thread.
116 void PostToOwnerThread(const tracked_objects::Location& from_here,
117 const base::Closure& fn) const;
118
119 private:
120 // May be used on any thread.
121 const scoped_refptr<base::MessageLoopProxy> owner_loop_proxy_;
122
123 DISALLOW_COPY_AND_ASSIGN(WeakHandleCoreBase);
124 };
125
126 // WeakHandleCore<T> contains all the logic for WeakHandle<T>.
127 template <typename T>
128 class WeakHandleCore
129 : public WeakHandleCoreBase,
130 public base::RefCountedThreadSafe<WeakHandleCore<T> > {
131 public:
132 // Must be called on |ptr|'s owner thread, which is assumed to be
133 // the current thread.
134 explicit WeakHandleCore(const base::WeakPtr<T>& ptr) : ptr_(ptr) {}
135
136 // Must be called on |ptr_|'s owner thread.
137 base::WeakPtr<T> Get() const {
138 CHECK(IsOnOwnerThread());
139 return ptr_;
140 }
141
142 // Call(...) may be called on any thread, but all its arguments
143 // should be safe to be bound and copied across threads.
144
145 template <typename U>
146 void Call(const tracked_objects::Location& from_here,
147 void (U::*fn)(void)) const {
148 PostToOwnerThread(
149 from_here,
150 Bind(&WeakHandleCore::template DoCall0<U>, this, fn));
151 }
152
153 template <typename U, typename A1>
154 void Call(const tracked_objects::Location& from_here,
155 void (U::*fn)(A1),
156 typename ParamTraits<A1>::ForwardType a1) const {
157 PostToOwnerThread(
158 from_here,
159 Bind(&WeakHandleCore::template DoCall1<U, A1>,
160 this, fn, a1));
161 }
162
163 template <typename U, typename A1, typename A2>
164 void Call(const tracked_objects::Location& from_here,
165 void (U::*fn)(A1, A2),
166 typename ParamTraits<A1>::ForwardType a1,
167 typename ParamTraits<A2>::ForwardType a2) const {
168 PostToOwnerThread(
169 from_here,
170 Bind(&WeakHandleCore::template DoCall2<U, A1, A2>,
171 this, fn, a1, a2));
172 }
173
174 template <typename U, typename A1, typename A2, typename A3>
175 void Call(const tracked_objects::Location& from_here,
176 void (U::*fn)(A1, A2, A3),
177 typename ParamTraits<A1>::ForwardType a1,
178 typename ParamTraits<A2>::ForwardType a2,
179 typename ParamTraits<A3>::ForwardType a3) const {
180 PostToOwnerThread(
181 from_here,
182 Bind(&WeakHandleCore::template DoCall3<U, A1, A2, A3>,
183 this, fn, a1, a2, a3));
184 }
185
186 template <typename U, typename A1, typename A2, typename A3, typename A4>
187 void Call(const tracked_objects::Location& from_here,
188 void (U::*fn)(A1, A2, A3, A4),
189 typename ParamTraits<A1>::ForwardType a1,
190 typename ParamTraits<A2>::ForwardType a2,
191 typename ParamTraits<A3>::ForwardType a3,
192 typename ParamTraits<A4>::ForwardType a4) const {
193 PostToOwnerThread(
194 from_here,
195 Bind(&WeakHandleCore::template DoCall4<U, A1, A2, A3, A4>,
196 this, fn, a1, a2, a3, a4));
197 }
198
199 private:
200 friend class base::RefCountedThreadSafe<WeakHandleCore<T> >;
201
202 // May be destroyed on any thread.
203 ~WeakHandleCore() {}
204
205 // GCC 4.2.1 on OS X gets confused if all the DoCall functions are
206 // named the same, so we distinguish them.
207
208 template <typename U>
209 void DoCall0(void (U::*fn)(void)) const {
210 CHECK(IsOnOwnerThread());
211 if (!Get()) {
212 return;
213 }
214 (Get()->*fn)();
215 }
216
217 template <typename U, typename A1>
218 void DoCall1(void (U::*fn)(A1),
219 typename ParamTraits<A1>::ForwardType a1) const {
220 CHECK(IsOnOwnerThread());
221 if (!Get()) {
222 return;
223 }
224 (Get()->*fn)(a1);
225 }
226
227 template <typename U, typename A1, typename A2>
228 void DoCall2(void (U::*fn)(A1, A2),
229 typename ParamTraits<A1>::ForwardType a1,
230 typename ParamTraits<A2>::ForwardType a2) const {
231 CHECK(IsOnOwnerThread());
232 if (!Get()) {
233 return;
234 }
235 (Get()->*fn)(a1, a2);
236 }
237
238 template <typename U, typename A1, typename A2, typename A3>
239 void DoCall3(void (U::*fn)(A1, A2, A3),
240 typename ParamTraits<A1>::ForwardType a1,
241 typename ParamTraits<A2>::ForwardType a2,
242 typename ParamTraits<A3>::ForwardType a3) const {
243 CHECK(IsOnOwnerThread());
244 if (!Get()) {
245 return;
246 }
247 (Get()->*fn)(a1, a2, a3);
248 }
249
250 template <typename U, typename A1, typename A2, typename A3, typename A4>
251 void DoCall4(void (U::*fn)(A1, A2, A3, A4),
252 typename ParamTraits<A1>::ForwardType a1,
253 typename ParamTraits<A2>::ForwardType a2,
254 typename ParamTraits<A3>::ForwardType a3,
255 typename ParamTraits<A4>::ForwardType a4) const {
256 CHECK(IsOnOwnerThread());
257 if (!Get()) {
258 return;
259 }
260 (Get()->*fn)(a1, a2, a3, a4);
261 }
262
263 // Must be dereferenced only on the owner thread. May be destroyed
264 // from any thread.
265 base::WeakPtr<T> ptr_;
266
267 DISALLOW_COPY_AND_ASSIGN(WeakHandleCore);
268 };
269
270 } // namespace internal
271
272 // May be destroyed on any thread.
273 // Copying and assignment are welcome.
274 template <typename T>
275 class WeakHandle {
276 public:
277 // Creates an uninitialized WeakHandle.
278 WeakHandle() {}
279
280 // Creates an initialized WeakHandle from |ptr|.
281 explicit WeakHandle(const base::WeakPtr<T>& ptr)
282 : core_(new internal::WeakHandleCore<T>(ptr)) {}
283
284 // Allow conversion from WeakHandle<U> to WeakHandle<T> if U is
285 // convertible to T, but we *must* be on |other|'s owner thread.
286 // Note that this doesn't override the regular copy constructor, so
287 // that one can be called on any thread.
288 template <typename U>
289 WeakHandle(const browser_sync::WeakHandle<U>& other) // NOLINT
290 : core_(
291 other.IsInitialized() ?
292 new internal::WeakHandleCore<T>(other.Get()) :
293 NULL) {}
294
295 // Returns true iff this WeakHandle is initialized. Note that being
296 // initialized isn't a guarantee that the underlying object is still
297 // alive.
298 bool IsInitialized() const {
299 return core_.get() != NULL;
300 }
301
302 // Resets to an uninitialized WeakHandle.
303 void Reset() {
304 core_ = NULL;
305 }
306
307 // Must be called only on the underlying object's owner thread.
308 base::WeakPtr<T> Get() const {
309 CHECK(IsInitialized());
310 CHECK(core_->IsOnOwnerThread());
311 return core_->Get();
312 }
313
314 // Call(...) may be called on any thread, but all its arguments
315 // should be safe to be bound and copied across threads.
316
317 template <typename U>
318 void Call(const tracked_objects::Location& from_here,
319 void (U::*fn)(void)) const {
320 CHECK(IsInitialized());
321 core_->Call(from_here, fn);
322 }
323
324 template <typename U, typename A1>
325 void Call(const tracked_objects::Location& from_here,
326 void (U::*fn)(A1),
327 typename internal::ParamTraits<A1>::ForwardType a1) const {
328 CHECK(IsInitialized());
329 core_->Call(from_here, fn, a1);
330 }
331
332 template <typename U, typename A1, typename A2>
333 void Call(const tracked_objects::Location& from_here,
334 void (U::*fn)(A1, A2),
335 typename internal::ParamTraits<A1>::ForwardType a1,
336 typename internal::ParamTraits<A2>::ForwardType a2) const {
337 CHECK(IsInitialized());
338 core_->Call(from_here, fn, a1, a2);
339 }
340
341 template <typename U, typename A1, typename A2, typename A3>
342 void Call(const tracked_objects::Location& from_here,
343 void (U::*fn)(A1, A2, A3),
344 typename internal::ParamTraits<A1>::ForwardType a1,
345 typename internal::ParamTraits<A2>::ForwardType a2,
346 typename internal::ParamTraits<A3>::ForwardType a3) const {
347 CHECK(IsInitialized());
348 core_->Call(from_here, fn, a1, a2, a3);
349 }
350
351 template <typename U, typename A1, typename A2, typename A3, typename A4>
352 void Call(const tracked_objects::Location& from_here,
353 void (U::*fn)(A1, A2, A3, A4),
354 typename internal::ParamTraits<A1>::ForwardType a1,
355 typename internal::ParamTraits<A2>::ForwardType a2,
356 typename internal::ParamTraits<A3>::ForwardType a3,
357 typename internal::ParamTraits<A4>::ForwardType a4) const {
358 CHECK(IsInitialized());
359 core_->Call(from_here, fn, a1, a2, a3, a4);
360 }
361
362 private:
363 FRIEND_TEST_ALL_PREFIXES(WeakHandleTest,
364 TypeConversionConstructor);
365 FRIEND_TEST_ALL_PREFIXES(WeakHandleTest,
366 TypeConversionConstructorAssignment);
367
368 scoped_refptr<internal::WeakHandleCore<T> > core_;
369 };
370
371 // Makes a WeakHandle from a WeakPtr.
372 template <typename T>
373 WeakHandle<T> MakeWeakHandle(const base::WeakPtr<T>& ptr) {
374 return WeakHandle<T>(ptr);
375 }
376
377 } // namespace browser_sync
378
379 #endif // CHROME_BROWSER_SYNC_UTIL_WEAK_HANDLE_H_
OLDNEW
« no previous file with comments | « chrome/browser/sync/util/user_settings.h ('k') | chrome/browser/sync/util/weak_handle.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698