OLD | NEW |
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 // Thread-safety notes: |
| 11 // When you get a WeakPtr (from a WeakPtrFactory or SupportsWeakPtr), |
| 12 // the WeakPtr becomes bound to the current thread. You may only |
| 13 // dereference the WeakPtr on that thread. However, it is safe to |
| 14 // destroy the WeakPtr object on another thread. |
| 15 // Since a WeakPtr object may be destroyed on a background thread, |
| 16 // querying WeakPtrFactory's HasWeakPtrs() method can be racy. |
| 17 // |
| 18 // |
10 // A common alternative to weak pointers is to have the shared object hold a | 19 // A common alternative to weak pointers is to have the shared object hold a |
11 // list of all referrers, and then when the shared object is destroyed, it | 20 // list of all referrers, and then when the shared object is destroyed, it |
12 // calls a method on the referrers to tell them to drop their references. This | 21 // calls a method on the referrers to tell them to drop their references. This |
13 // approach also requires the referrers to tell the shared object when they get | 22 // approach also requires the referrers to tell the shared object when they get |
14 // destroyed so that the shared object can remove the referrer from its list of | 23 // destroyed so that the shared object can remove the referrer from its list of |
15 // referrers. Such a solution works, but it is a bit complex. | 24 // referrers. Such a solution works, but it is a bit complex. |
16 // | 25 // |
17 // EXAMPLE: | 26 // EXAMPLE: |
18 // | 27 // |
19 // class Controller : public SupportsWeakPtr<Controller> { | 28 // class Controller : public SupportsWeakPtr<Controller> { |
(...skipping 18 matching lines...) Expand all Loading... |
38 // WeakPtr<Controller> controller_; | 47 // WeakPtr<Controller> controller_; |
39 // }; | 48 // }; |
40 // | 49 // |
41 // Given the above classes, a consumer may allocate a Controller object, call | 50 // Given the above classes, a consumer may allocate a Controller object, call |
42 // SpawnWorker several times, and then destroy the Controller object before all | 51 // 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 | 52 // 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 | 53 // pointer to the Controller, we don't have to worry about the Worker |
45 // dereferencing the Controller back pointer after the Controller has been | 54 // dereferencing the Controller back pointer after the Controller has been |
46 // destroyed. | 55 // destroyed. |
47 // | 56 // |
48 // WARNING: weak pointers are not threadsafe!!! You must only use a WeakPtr | |
49 // instance on thread where it was created. | |
50 | 57 |
51 #ifndef BASE_MEMORY_WEAK_PTR_H_ | 58 #ifndef BASE_MEMORY_WEAK_PTR_H_ |
52 #define BASE_MEMORY_WEAK_PTR_H_ | 59 #define BASE_MEMORY_WEAK_PTR_H_ |
53 #pragma once | 60 #pragma once |
54 | 61 |
55 #include "base/base_export.h" | 62 #include "base/base_export.h" |
56 #include "base/logging.h" | 63 #include "base/logging.h" |
57 #include "base/memory/ref_counted.h" | 64 #include "base/memory/ref_counted.h" |
58 #include "base/threading/thread_checker.h" | 65 #include "base/threading/thread_checker.h" |
59 | 66 |
60 namespace base { | 67 namespace base { |
61 | 68 |
62 namespace internal { | 69 namespace internal { |
63 // These classes are part of the WeakPtr implementation. | 70 // These classes are part of the WeakPtr implementation. |
64 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF. | 71 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF. |
65 | 72 |
66 class BASE_EXPORT WeakReference { | 73 class BASE_EXPORT WeakReference { |
67 public: | 74 public: |
68 // While Flag is bound to a specific thread, it may be deleted from another | 75 // While Flag is bound to a specific thread, it may be deleted from another |
69 // via base::WeakPtr::~WeakPtr(). | 76 // via base::WeakPtr::~WeakPtr(). |
70 class Flag : public RefCountedThreadSafe<Flag> { | 77 class Flag : public RefCountedThreadSafe<Flag> { |
71 public: | 78 public: |
72 explicit Flag(Flag** handle); | 79 Flag(); |
73 | 80 |
74 void Invalidate(); | 81 void Invalidate(); |
75 bool IsValid() const; | 82 bool IsValid() const; |
76 | 83 |
77 void DetachFromThread() { thread_checker_.DetachFromThread(); } | 84 void DetachFromThread() { thread_checker_.DetachFromThread(); } |
78 | 85 |
79 private: | 86 private: |
80 friend class base::RefCountedThreadSafe<Flag>; | 87 friend class base::RefCountedThreadSafe<Flag>; |
81 | 88 |
82 ~Flag(); | 89 ~Flag(); |
83 | 90 |
84 ThreadChecker thread_checker_; | 91 ThreadChecker thread_checker_; |
85 Flag** handle_; | 92 bool is_valid_; |
86 }; | 93 }; |
87 | 94 |
88 WeakReference(); | 95 WeakReference(); |
89 WeakReference(Flag* flag); | 96 explicit WeakReference(const Flag* flag); |
90 ~WeakReference(); | 97 ~WeakReference(); |
91 | 98 |
92 bool is_valid() const; | 99 bool is_valid() const; |
93 | 100 |
94 private: | 101 private: |
95 scoped_refptr<Flag> flag_; | 102 scoped_refptr<const Flag> flag_; |
96 }; | 103 }; |
97 | 104 |
98 class BASE_EXPORT WeakReferenceOwner { | 105 class BASE_EXPORT WeakReferenceOwner { |
99 public: | 106 public: |
100 WeakReferenceOwner(); | 107 WeakReferenceOwner(); |
101 ~WeakReferenceOwner(); | 108 ~WeakReferenceOwner(); |
102 | 109 |
103 WeakReference GetRef() const; | 110 WeakReference GetRef() const; |
104 | 111 |
105 bool HasRefs() const { | 112 bool HasRefs() const { |
106 return flag_ != NULL; | 113 return flag_.get() && !flag_->HasOneRef(); |
107 } | 114 } |
108 | 115 |
109 void Invalidate(); | 116 void Invalidate(); |
110 | 117 |
111 // Indicates that this object will be used on another thread from now on. | 118 // Indicates that this object will be used on another thread from now on. |
112 void DetachFromThread() { | 119 void DetachFromThread() { |
113 if (flag_) flag_->DetachFromThread(); | 120 if (flag_) flag_->DetachFromThread(); |
114 } | 121 } |
115 | 122 |
116 private: | 123 private: |
117 mutable WeakReference::Flag* flag_; | 124 mutable scoped_refptr<WeakReference::Flag> flag_; |
118 }; | 125 }; |
119 | 126 |
120 // This class simplifies the implementation of WeakPtr's type conversion | 127 // This class simplifies the implementation of WeakPtr's type conversion |
121 // constructor by avoiding the need for a public accessor for ref_. A | 128 // 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 | 129 // 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. | 130 // base class gives us a way to access ref_ in a protected fashion. |
124 class BASE_EXPORT WeakPtrBase { | 131 class BASE_EXPORT WeakPtrBase { |
125 public: | 132 public: |
126 WeakPtrBase(); | 133 WeakPtrBase(); |
127 ~WeakPtrBase(); | 134 ~WeakPtrBase(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 | 253 |
247 private: | 254 private: |
248 internal::WeakReferenceOwner weak_reference_owner_; | 255 internal::WeakReferenceOwner weak_reference_owner_; |
249 T* ptr_; | 256 T* ptr_; |
250 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); | 257 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); |
251 }; | 258 }; |
252 | 259 |
253 } // namespace base | 260 } // namespace base |
254 | 261 |
255 #endif // BASE_MEMORY_WEAK_PTR_H_ | 262 #endif // BASE_MEMORY_WEAK_PTR_H_ |
OLD | NEW |