| 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 |