• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #ifndef STORAGE_BROWSER_FILEAPI_TASK_RUNNER_BOUND_OBSERVER_LIST_H_
6 #define STORAGE_BROWSER_FILEAPI_TASK_RUNNER_BOUND_OBSERVER_LIST_H_
7 
8 #include <map>
9 
10 #include "base/basictypes.h"
11 #include "base/bind.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/sequenced_task_runner.h"
14 #include "base/threading/thread.h"
15 
16 namespace storage {
17 
18 // A wrapper for dispatching method.
19 template <class T, class Method, class Params>
NotifyWrapper(T obj,Method m,const Params & p)20 void NotifyWrapper(T obj, Method m, const Params& p) {
21   DispatchToMethod(base::internal::UnwrapTraits<T>::Unwrap(obj), m, p);
22 }
23 
24 // An observer list helper to notify on a given task runner.
25 // Observer pointers (stored as ObserverStoreType) must be kept alive
26 // until this list dispatches all the notifications.
27 //
28 // Unlike regular ObserverList or ObserverListThreadSafe internal observer
29 // list is immutable (though not declared const) and cannot be modified after
30 // constructed.
31 //
32 // It is ok to specify scoped_refptr<Observer> as ObserverStoreType to
33 // explicitly keep references if necessary.
34 template <class Observer, class ObserverStoreType = Observer*>
35 class TaskRunnerBoundObserverList {
36  public:
37   typedef scoped_refptr<base::SequencedTaskRunner> TaskRunnerPtr;
38   typedef std::map<ObserverStoreType, TaskRunnerPtr> ObserversListMap;
39 
40   // Creates an empty list.
41   TaskRunnerBoundObserverList<Observer, ObserverStoreType>() {}
42 
43   // Creates a new list with given |observers|.
44   explicit TaskRunnerBoundObserverList<Observer, ObserverStoreType>(
45       const ObserversListMap& observers)
observers_(observers)46       : observers_(observers) {}
47 
48   virtual ~TaskRunnerBoundObserverList<Observer, ObserverStoreType>() {}
49 
50   // Returns a new observer list with given observer.
51   // It is valid to give NULL as |runner_to_notify|, and in that case
52   // notifications are dispatched on the current runner.
53   // Note that this is a const method and does NOT change 'this' observer
54   // list but returns a new list.
AddObserver(Observer * observer,base::SequencedTaskRunner * runner_to_notify)55   TaskRunnerBoundObserverList<Observer, ObserverStoreType> AddObserver(
56       Observer* observer,
57       base::SequencedTaskRunner* runner_to_notify) const {
58     ObserversListMap observers = observers_;
59     observers.insert(std::make_pair(observer, runner_to_notify));
60     return TaskRunnerBoundObserverList<Observer, ObserverStoreType>(observers);
61   }
62 
63   // Notify on the task runner that is given to AddObserver.
64   // If we're already on the runner this just dispatches the method.
65   template <class Method, class Params>
Notify(Method method,const Params & params)66   void Notify(Method method, const Params& params) const {
67     COMPILE_ASSERT(
68         (base::internal::ParamsUseScopedRefptrCorrectly<Params>::value),
69         badunboundmethodparams);
70     for (typename ObserversListMap::const_iterator it = observers_.begin();
71          it != observers_.end(); ++it) {
72       if (!it->second.get() || it->second->RunsTasksOnCurrentThread()) {
73         DispatchToMethod(UnwrapTraits::Unwrap(it->first), method, params);
74         continue;
75       }
76       it->second->PostTask(
77           FROM_HERE,
78           base::Bind(&NotifyWrapper<ObserverStoreType, Method, Params>,
79                      it->first, method, params));
80     }
81   }
82 
83  private:
84   typedef base::internal::UnwrapTraits<ObserverStoreType> UnwrapTraits;
85 
86   ObserversListMap observers_;
87 };
88 
89 class FileAccessObserver;
90 class FileChangeObserver;
91 class FileUpdateObserver;
92 
93 typedef TaskRunnerBoundObserverList<FileAccessObserver> AccessObserverList;
94 typedef TaskRunnerBoundObserverList<FileChangeObserver> ChangeObserverList;
95 typedef TaskRunnerBoundObserverList<FileUpdateObserver> UpdateObserverList;
96 
97 }  // namespace storage
98 
99 #endif  // STORAGE_BROWSER_FILEAPI_TASK_RUNNER_BOUND_OBSERVER_LIST_H_
100