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

Side by Side Diff: base/observer_list_threadsafe.h

Issue 369703003: Reduce usage of MessageLoopProxy in base/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 6 years, 2 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 | « base/memory/ref_counted_delete_on_task_runner.h ('k') | base/prefs/json_pref_store.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 10
11 #include "base/basictypes.h" 11 #include "base/basictypes.h"
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/memory/ref_counted.h" 15 #include "base/memory/ref_counted.h"
16 #include "base/message_loop/message_loop.h" 16 #include "base/message_loop/message_loop.h"
17 #include "base/message_loop/message_loop_proxy.h"
18 #include "base/observer_list.h" 17 #include "base/observer_list.h"
18 #include "base/single_thread_task_runner.h"
19 #include "base/stl_util.h" 19 #include "base/stl_util.h"
20 #include "base/thread_task_runner_handle.h"
20 #include "base/threading/platform_thread.h" 21 #include "base/threading/platform_thread.h"
21 22
22 /////////////////////////////////////////////////////////////////////////////// 23 ///////////////////////////////////////////////////////////////////////////////
23 // 24 //
24 // OVERVIEW: 25 // OVERVIEW:
25 // 26 //
26 // A thread-safe container for a list of observers. 27 // A thread-safe container for a list of observers.
27 // This is similar to the observer_list (see observer_list.h), but it 28 // This is similar to the observer_list (see observer_list.h), but it
28 // is more robust for multi-threaded situations. 29 // is more robust for multi-threaded situations.
29 // 30 //
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 } 202 }
202 203
203 // TODO(mbelshe): Add more wrappers for Notify() with more arguments. 204 // TODO(mbelshe): Add more wrappers for Notify() with more arguments.
204 205
205 private: 206 private:
206 // See comment above ObserverListThreadSafeTraits' definition. 207 // See comment above ObserverListThreadSafeTraits' definition.
207 friend struct ObserverListThreadSafeTraits<ObserverType>; 208 friend struct ObserverListThreadSafeTraits<ObserverType>;
208 209
209 struct ObserverListContext { 210 struct ObserverListContext {
210 explicit ObserverListContext(NotificationType type) 211 explicit ObserverListContext(NotificationType type)
211 : loop(base::MessageLoopProxy::current()), 212 : task_runner(base::ThreadTaskRunnerHandle::Get()), list(type) {}
212 list(type) {
213 }
214 213
215 scoped_refptr<base::MessageLoopProxy> loop; 214 scoped_refptr<base::SingleThreadTaskRunner> task_runner;
216 ObserverList<ObserverType> list; 215 ObserverList<ObserverType> list;
217 216
218 DISALLOW_COPY_AND_ASSIGN(ObserverListContext); 217 DISALLOW_COPY_AND_ASSIGN(ObserverListContext);
219 }; 218 };
220 219
221 ~ObserverListThreadSafe() { 220 ~ObserverListThreadSafe() {
222 STLDeleteValues(&observer_lists_); 221 STLDeleteValues(&observer_lists_);
223 } 222 }
224 223
225 template <class Method, class Params> 224 template <class Method, class Params>
226 void Notify(const UnboundMethod<ObserverType, Method, Params>& method) { 225 void Notify(const UnboundMethod<ObserverType, Method, Params>& method) {
227 base::AutoLock lock(list_lock_); 226 base::AutoLock lock(list_lock_);
228 typename ObserversListMap::iterator it; 227 typename ObserversListMap::iterator it;
229 for (it = observer_lists_.begin(); it != observer_lists_.end(); ++it) { 228 for (it = observer_lists_.begin(); it != observer_lists_.end(); ++it) {
230 ObserverListContext* context = (*it).second; 229 ObserverListContext* context = (*it).second;
231 context->loop->PostTask( 230 context->task_runner->PostTask(
232 FROM_HERE, 231 FROM_HERE,
233 base::Bind(&ObserverListThreadSafe<ObserverType>:: 232 base::Bind(&ObserverListThreadSafe<
234 template NotifyWrapper<Method, Params>, this, context, method)); 233 ObserverType>::template NotifyWrapper<Method, Params>,
234 this,
235 context,
236 method));
235 } 237 }
236 } 238 }
237 239
238 // Wrapper which is called to fire the notifications for each thread's 240 // Wrapper which is called to fire the notifications for each thread's
239 // ObserverList. This function MUST be called on the thread which owns 241 // ObserverList. This function MUST be called on the thread which owns
240 // the unsafe ObserverList. 242 // the unsafe ObserverList.
241 template <class Method, class Params> 243 template <class Method, class Params>
242 void NotifyWrapper(ObserverListContext* context, 244 void NotifyWrapper(ObserverListContext* context,
243 const UnboundMethod<ObserverType, Method, Params>& method) { 245 const UnboundMethod<ObserverType, Method, Params>& method) {
244 246
245 // Check that this list still needs notifications. 247 // Check that this list still needs notifications.
246 { 248 {
247 base::AutoLock lock(list_lock_); 249 base::AutoLock lock(list_lock_);
248 typename ObserversListMap::iterator it = 250 typename ObserversListMap::iterator it =
249 observer_lists_.find(base::PlatformThread::CurrentId()); 251 observer_lists_.find(base::PlatformThread::CurrentId());
250 252
251 // The ObserverList could have been removed already. In fact, it could 253 // The ObserverList could have been removed already. In fact, it could
252 // have been removed and then re-added! If the master list's loop 254 // have been removed and then re-added! If the master list's task runner
253 // does not match this one, then we do not need to finish this 255 // does not match this one, then we do not need to finish this
254 // notification. 256 // notification.
255 if (it == observer_lists_.end() || it->second != context) 257 if (it == observer_lists_.end() || it->second != context)
256 return; 258 return;
257 } 259 }
258 260
259 { 261 {
260 typename ObserverList<ObserverType>::Iterator it(context->list); 262 typename ObserverList<ObserverType>::Iterator it(context->list);
261 ObserverType* obs; 263 ObserverType* obs;
262 while ((obs = it.GetNext()) != NULL) 264 while ((obs = it.GetNext()) != NULL)
(...skipping 23 matching lines...) Expand all
286 ObserversListMap; 288 ObserversListMap;
287 289
288 mutable base::Lock list_lock_; // Protects the observer_lists_. 290 mutable base::Lock list_lock_; // Protects the observer_lists_.
289 ObserversListMap observer_lists_; 291 ObserversListMap observer_lists_;
290 const NotificationType type_; 292 const NotificationType type_;
291 293
292 DISALLOW_COPY_AND_ASSIGN(ObserverListThreadSafe); 294 DISALLOW_COPY_AND_ASSIGN(ObserverListThreadSafe);
293 }; 295 };
294 296
295 #endif // BASE_OBSERVER_LIST_THREADSAFE_H_ 297 #endif // BASE_OBSERVER_LIST_THREADSAFE_H_
OLDNEW
« no previous file with comments | « base/memory/ref_counted_delete_on_task_runner.h ('k') | base/prefs/json_pref_store.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698