OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #ifndef BASE_OBSERVER_LIST_THREADSAFE_H_ | 5 #ifndef BASE_OBSERVER_LIST_THREADSAFE_H_ |
6 #define BASE_OBSERVER_LIST_THREADSAFE_H_ | 6 #define BASE_OBSERVER_LIST_THREADSAFE_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <map> | 10 #include <map> |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 // whereas with the non-thread-safe observer_list, notifications happen | 42 // whereas with the non-thread-safe observer_list, notifications happen |
43 // synchronously and immediately. | 43 // synchronously and immediately. |
44 // | 44 // |
45 // IMPLEMENTATION NOTES | 45 // IMPLEMENTATION NOTES |
46 // The ObserverListThreadSafe maintains an ObserverList for each thread | 46 // The ObserverListThreadSafe maintains an ObserverList for each thread |
47 // which uses the ThreadSafeObserver. When Notifying the observers, | 47 // which uses the ThreadSafeObserver. When Notifying the observers, |
48 // we simply call PostTask to each registered thread, and then each thread | 48 // we simply call PostTask to each registered thread, and then each thread |
49 // will notify its regular ObserverList. | 49 // will notify its regular ObserverList. |
50 // | 50 // |
51 /////////////////////////////////////////////////////////////////////////////// | 51 /////////////////////////////////////////////////////////////////////////////// |
| 52 |
| 53 // Forward declaration for ObserverListThreadSafeTraits. |
| 54 template <class ObserverType> |
| 55 class ObserverListThreadSafe; |
| 56 |
| 57 // This class is used to work around VS2005 not accepting: |
| 58 // |
| 59 // friend class |
| 60 // base::RefCountedThreadSafe<ObserverListThreadSafe<ObserverType> >; |
| 61 // |
| 62 // Instead of friending the class, we could friend the actual function |
| 63 // which calls delete. However, this ends up being |
| 64 // RefCountedThreadSafe::DeleteInternal(), which is private. So we |
| 65 // define our own templated traits class so we can friend it. |
| 66 template <class T> |
| 67 struct ObserverListThreadSafeTraits { |
| 68 static void Destruct(const ObserverListThreadSafe<T>* x) { |
| 69 delete x; |
| 70 } |
| 71 }; |
| 72 |
52 template <class ObserverType> | 73 template <class ObserverType> |
53 class ObserverListThreadSafe | 74 class ObserverListThreadSafe |
54 : public base::RefCountedThreadSafe<ObserverListThreadSafe<ObserverType> > { | 75 : public base::RefCountedThreadSafe< |
| 76 ObserverListThreadSafe<ObserverType>, |
| 77 ObserverListThreadSafeTraits<ObserverType> > { |
55 public: | 78 public: |
56 typedef typename ObserverList<ObserverType>::NotificationType | 79 typedef typename ObserverList<ObserverType>::NotificationType |
57 NotificationType; | 80 NotificationType; |
58 | 81 |
59 ObserverListThreadSafe() | 82 ObserverListThreadSafe() |
60 : type_(ObserverListBase<ObserverType>::NOTIFY_ALL) {} | 83 : type_(ObserverListBase<ObserverType>::NOTIFY_ALL) {} |
61 explicit ObserverListThreadSafe(NotificationType type) : type_(type) {} | 84 explicit ObserverListThreadSafe(NotificationType type) : type_(type) {} |
62 | 85 |
63 // Add an observer to the list. | 86 // Add an observer to the list. |
64 void AddObserver(ObserverType* obs) { | 87 void AddObserver(ObserverType* obs) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 | 146 |
124 template <class Method, class A> | 147 template <class Method, class A> |
125 void Notify(Method m, const A &a) { | 148 void Notify(Method m, const A &a) { |
126 UnboundMethod<ObserverType, Method, Tuple1<A> > method(m, MakeTuple(a)); | 149 UnboundMethod<ObserverType, Method, Tuple1<A> > method(m, MakeTuple(a)); |
127 Notify<Method, Tuple1<A> >(method); | 150 Notify<Method, Tuple1<A> >(method); |
128 } | 151 } |
129 | 152 |
130 // TODO(mbelshe): Add more wrappers for Notify() with more arguments. | 153 // TODO(mbelshe): Add more wrappers for Notify() with more arguments. |
131 | 154 |
132 private: | 155 private: |
133 friend class | 156 // See comment above ObserverListThreadSafeTraits' definition. |
134 base::RefCountedThreadSafe<ObserverListThreadSafe<ObserverType> >; | 157 friend struct ObserverListThreadSafeTraits<ObserverType>; |
| 158 |
135 ~ObserverListThreadSafe() { | 159 ~ObserverListThreadSafe() { |
136 typename ObserversListMap::const_iterator it; | 160 typename ObserversListMap::const_iterator it; |
137 for (it = observer_lists_.begin(); it != observer_lists_.end(); ++it) | 161 for (it = observer_lists_.begin(); it != observer_lists_.end(); ++it) |
138 delete (*it).second; | 162 delete (*it).second; |
139 observer_lists_.clear(); | 163 observer_lists_.clear(); |
140 } | 164 } |
141 | 165 |
142 template <class Method, class Params> | 166 template <class Method, class Params> |
143 void Notify(const UnboundMethod<ObserverType, Method, Params>& method) { | 167 void Notify(const UnboundMethod<ObserverType, Method, Params>& method) { |
144 AutoLock lock(list_lock_); | 168 AutoLock lock(list_lock_); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 | 226 |
203 // These are marked mutable to facilitate having NotifyAll be const. | 227 // These are marked mutable to facilitate having NotifyAll be const. |
204 Lock list_lock_; // Protects the observer_lists_. | 228 Lock list_lock_; // Protects the observer_lists_. |
205 ObserversListMap observer_lists_; | 229 ObserversListMap observer_lists_; |
206 const NotificationType type_; | 230 const NotificationType type_; |
207 | 231 |
208 DISALLOW_COPY_AND_ASSIGN(ObserverListThreadSafe); | 232 DISALLOW_COPY_AND_ASSIGN(ObserverListThreadSafe); |
209 }; | 233 }; |
210 | 234 |
211 #endif // BASE_OBSERVER_LIST_THREADSAFE_H_ | 235 #endif // BASE_OBSERVER_LIST_THREADSAFE_H_ |
OLD | NEW |