OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 | 7 |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <map> | 9 #include <map> |
10 #include <tuple> | 10 #include <tuple> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/location.h" | 13 #include "base/location.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/macros.h" | 15 #include "base/macros.h" |
16 #include "base/memory/ref_counted.h" | 16 #include "base/memory/ref_counted.h" |
17 #include "base/message_loop/message_loop.h" | |
18 #include "base/observer_list.h" | 17 #include "base/observer_list.h" |
19 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
20 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
21 #include "base/threading/platform_thread.h" | 20 #include "base/threading/platform_thread.h" |
22 #include "base/threading/thread_task_runner_handle.h" | 21 #include "base/threading/thread_task_runner_handle.h" |
23 | 22 |
24 /////////////////////////////////////////////////////////////////////////////// | 23 /////////////////////////////////////////////////////////////////////////////// |
25 // | 24 // |
26 // OVERVIEW: | 25 // OVERVIEW: |
27 // | 26 // |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 typedef typename ObserverList<ObserverType>::NotificationType | 105 typedef typename ObserverList<ObserverType>::NotificationType |
107 NotificationType; | 106 NotificationType; |
108 | 107 |
109 ObserverListThreadSafe() | 108 ObserverListThreadSafe() |
110 : type_(ObserverListBase<ObserverType>::NOTIFY_ALL) {} | 109 : type_(ObserverListBase<ObserverType>::NOTIFY_ALL) {} |
111 explicit ObserverListThreadSafe(NotificationType type) : type_(type) {} | 110 explicit ObserverListThreadSafe(NotificationType type) : type_(type) {} |
112 | 111 |
113 // Add an observer to the list. An observer should not be added to | 112 // Add an observer to the list. An observer should not be added to |
114 // the same list more than once. | 113 // the same list more than once. |
115 void AddObserver(ObserverType* obs) { | 114 void AddObserver(ObserverType* obs) { |
116 // If there is not a current MessageLoop, it is impossible to notify on it, | 115 // If there is no ThreadTaskRunnerHandle, it is impossible to notify on it, |
117 // so do not add the observer. | 116 // so do not add the observer. |
118 if (!MessageLoop::current()) | 117 if (!ThreadTaskRunnerHandle::IsSet()) |
119 return; | 118 return; |
120 | 119 |
121 ObserverList<ObserverType>* list = nullptr; | 120 ObserverList<ObserverType>* list = nullptr; |
122 PlatformThreadId thread_id = PlatformThread::CurrentId(); | 121 PlatformThreadId thread_id = PlatformThread::CurrentId(); |
123 { | 122 { |
124 AutoLock lock(list_lock_); | 123 AutoLock lock(list_lock_); |
125 if (observer_lists_.find(thread_id) == observer_lists_.end()) | 124 if (observer_lists_.find(thread_id) == observer_lists_.end()) |
126 observer_lists_[thread_id] = new ObserverListContext(type_); | 125 observer_lists_[thread_id] = new ObserverListContext(type_); |
127 list = &(observer_lists_[thread_id]->list); | 126 list = &(observer_lists_[thread_id]->list); |
128 } | 127 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 typename ObserversListMap::iterator it = | 248 typename ObserversListMap::iterator it = |
250 observer_lists_.find(PlatformThread::CurrentId()); | 249 observer_lists_.find(PlatformThread::CurrentId()); |
251 if (it != observer_lists_.end() && it->second == context) | 250 if (it != observer_lists_.end() && it->second == context) |
252 observer_lists_.erase(it); | 251 observer_lists_.erase(it); |
253 } | 252 } |
254 delete context; | 253 delete context; |
255 } | 254 } |
256 } | 255 } |
257 | 256 |
258 // Key by PlatformThreadId because in tests, clients can attempt to remove | 257 // Key by PlatformThreadId because in tests, clients can attempt to remove |
259 // observers without a MessageLoop. If this were keyed by MessageLoop, that | 258 // observers without a SingleThreadTaskRunner. If this were keyed by |
260 // operation would be silently ignored, leaving garbage in the ObserverList. | 259 // SingleThreadTaskRunner, that operation would be silently ignored, leaving |
| 260 // garbage in the ObserverList. |
261 typedef std::map<PlatformThreadId, ObserverListContext*> | 261 typedef std::map<PlatformThreadId, ObserverListContext*> |
262 ObserversListMap; | 262 ObserversListMap; |
263 | 263 |
264 mutable Lock list_lock_; // Protects the observer_lists_. | 264 mutable Lock list_lock_; // Protects the observer_lists_. |
265 ObserversListMap observer_lists_; | 265 ObserversListMap observer_lists_; |
266 const NotificationType type_; | 266 const NotificationType type_; |
267 | 267 |
268 DISALLOW_COPY_AND_ASSIGN(ObserverListThreadSafe); | 268 DISALLOW_COPY_AND_ASSIGN(ObserverListThreadSafe); |
269 }; | 269 }; |
270 | 270 |
271 } // namespace base | 271 } // namespace base |
272 | 272 |
273 #endif // BASE_OBSERVER_LIST_THREADSAFE_H_ | 273 #endif // BASE_OBSERVER_LIST_THREADSAFE_H_ |
OLD | NEW |