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

Side by Side Diff: base/memory/weak_ptr.h

Issue 7677028: Make WeakPtr thread-safe, i.e. allow cross-thread copying of WeakPtr (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address comments, add a unit test Created 9 years, 4 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 | « no previous file | base/memory/weak_ptr.cc » ('j') | base/memory/weak_ptr.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 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 pointers help in cases where you have many objects referring back to a 5 // Weak pointers help in cases where you have many objects referring back to a
6 // shared object and you wish for the lifetime of the shared object to not be 6 // shared object and you wish for the lifetime of the shared object to not be
7 // bound to the lifetime of the referrers. In other words, this is useful when 7 // bound to the lifetime of the referrers. In other words, this is useful when
8 // reference counting is not a good fit. 8 // reference counting is not a good fit.
9 // 9 //
10 // A common alternative to weak pointers is to have the shared object hold a 10 // A common alternative to weak pointers is to have the shared object hold a
(...skipping 27 matching lines...) Expand all
38 // WeakPtr<Controller> controller_; 38 // WeakPtr<Controller> controller_;
39 // }; 39 // };
40 // 40 //
41 // Given the above classes, a consumer may allocate a Controller object, call 41 // Given the above classes, a consumer may allocate a Controller object, call
42 // SpawnWorker several times, and then destroy the Controller object before all 42 // SpawnWorker several times, and then destroy the Controller object before all
43 // of the workers have completed. Because the Worker class only holds a weak 43 // of the workers have completed. Because the Worker class only holds a weak
44 // pointer to the Controller, we don't have to worry about the Worker 44 // pointer to the Controller, we don't have to worry about the Worker
45 // dereferencing the Controller back pointer after the Controller has been 45 // dereferencing the Controller back pointer after the Controller has been
46 // destroyed. 46 // destroyed.
47 // 47 //
48 // WARNING: weak pointers are not threadsafe!!! You must only use a WeakPtr 48 // Thread-safety notes: Weak pointers may only be dereferenced on the thread
darin (slow to review) 2011/08/18 20:29:52 This passage is a bit complicated. I think you mi
49 // instance on thread where it was created. 49 // on which the object being pointed to will be deleted. However, WeakPtr
50 // references themselves may be be passed, copied and destroyed across threads.
51 // Whenever there are no weak references, the thread on which the first
52 // reference is created initializes the thread-safety checks with respect
53 // to querying and invalidating the reference.
54 // Getting the initial reference and querying HasWeakPtrs()/HasRefs() also
55 // should only be done on the owning thread and the user has to avoid races.
56 // Again, note that you can however create an object on one thread, and
57 // then transfer ownership to another thread on which it will be deleted.
58 // When transferring ownership, all previous weak references must first be
59 // released.
50 60
51 #ifndef BASE_MEMORY_WEAK_PTR_H_ 61 #ifndef BASE_MEMORY_WEAK_PTR_H_
52 #define BASE_MEMORY_WEAK_PTR_H_ 62 #define BASE_MEMORY_WEAK_PTR_H_
53 #pragma once 63 #pragma once
54 64
55 #include "base/base_export.h" 65 #include "base/base_export.h"
56 #include "base/logging.h" 66 #include "base/logging.h"
57 #include "base/memory/ref_counted.h" 67 #include "base/memory/ref_counted.h"
58 #include "base/threading/thread_checker.h" 68 #include "base/threading/thread_checker.h"
59 69
60 namespace base { 70 namespace base {
61 71
62 namespace internal { 72 namespace internal {
63 // These classes are part of the WeakPtr implementation. 73 // These classes are part of the WeakPtr implementation.
64 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF. 74 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF.
65 75
66 class BASE_EXPORT WeakReference { 76 class BASE_EXPORT WeakReference {
67 public: 77 public:
68 // While Flag is bound to a specific thread, it may be deleted from another 78 // While Flag is bound to a specific thread, it may be deleted from another
69 // via base::WeakPtr::~WeakPtr(). 79 // via base::WeakPtr::~WeakPtr().
70 class Flag : public RefCountedThreadSafe<Flag> { 80 class Flag : public RefCountedThreadSafe<Flag> {
71 public: 81 public:
72 explicit Flag(Flag** handle); 82 explicit Flag();
73 83
74 void Invalidate(); 84 void Invalidate();
75 bool IsValid() const; 85 bool IsValid() const;
76 86
77 void DetachFromThread() { thread_checker_.DetachFromThread(); } 87 void DetachFromThread() { thread_checker_.DetachFromThread(); }
78 88
79 private: 89 private:
80 friend class base::RefCountedThreadSafe<Flag>; 90 friend class base::RefCountedThreadSafe<Flag>;
81 91
82 ~Flag(); 92 ~Flag();
83 93
84 ThreadChecker thread_checker_; 94 ThreadChecker thread_checker_;
85 Flag** handle_; 95 bool is_valid_;
86 }; 96 };
87 97
88 WeakReference(); 98 WeakReference();
89 WeakReference(Flag* flag); 99 WeakReference(const Flag* flag);
90 ~WeakReference(); 100 ~WeakReference();
91 101
92 bool is_valid() const; 102 bool is_valid() const;
93 103
94 private: 104 private:
95 scoped_refptr<Flag> flag_; 105 scoped_refptr<const Flag> flag_;
96 }; 106 };
97 107
98 class BASE_EXPORT WeakReferenceOwner { 108 class BASE_EXPORT WeakReferenceOwner {
99 public: 109 public:
100 WeakReferenceOwner(); 110 WeakReferenceOwner();
101 ~WeakReferenceOwner(); 111 ~WeakReferenceOwner();
102 112
103 WeakReference GetRef() const; 113 WeakReference GetRef() const;
104 114
105 bool HasRefs() const { 115 bool HasRefs() const {
106 return flag_ != NULL; 116 return flag_.get() && !flag_->HasOneRef();
107 } 117 }
108 118
109 void Invalidate(); 119 void Invalidate();
110 120
111 // Indicates that this object will be used on another thread from now on. 121 // Indicates that this object will be used on another thread from now on.
112 void DetachFromThread() { 122 void DetachFromThread() {
113 if (flag_) flag_->DetachFromThread(); 123 if (flag_) flag_->DetachFromThread();
114 } 124 }
115 125
116 private: 126 private:
117 mutable WeakReference::Flag* flag_; 127 mutable scoped_refptr<WeakReference::Flag> flag_;
118 }; 128 };
119 129
120 // This class simplifies the implementation of WeakPtr's type conversion 130 // This class simplifies the implementation of WeakPtr's type conversion
121 // constructor by avoiding the need for a public accessor for ref_. A 131 // constructor by avoiding the need for a public accessor for ref_. A
122 // WeakPtr<T> cannot access the private members of WeakPtr<U>, so this 132 // WeakPtr<T> cannot access the private members of WeakPtr<U>, so this
123 // base class gives us a way to access ref_ in a protected fashion. 133 // base class gives us a way to access ref_ in a protected fashion.
124 class BASE_EXPORT WeakPtrBase { 134 class BASE_EXPORT WeakPtrBase {
125 public: 135 public:
126 WeakPtrBase(); 136 WeakPtrBase();
127 ~WeakPtrBase(); 137 ~WeakPtrBase();
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 256
247 private: 257 private:
248 internal::WeakReferenceOwner weak_reference_owner_; 258 internal::WeakReferenceOwner weak_reference_owner_;
249 T* ptr_; 259 T* ptr_;
250 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); 260 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory);
251 }; 261 };
252 262
253 } // namespace base 263 } // namespace base
254 264
255 #endif // BASE_MEMORY_WEAK_PTR_H_ 265 #endif // BASE_MEMORY_WEAK_PTR_H_
OLDNEW
« no previous file with comments | « no previous file | base/memory/weak_ptr.cc » ('j') | base/memory/weak_ptr.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698