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.
5 #ifndef STORAGE_BROWSER_FILEAPI_TASK_RUNNER_BOUND_OBSERVER_LIST_H_
6 #define STORAGE_BROWSER_FILEAPI_TASK_RUNNER_BOUND_OBSERVER_LIST_H_
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"
18 // A wrapper for dispatching method.
19 template <class T
, class Method
, class Params
>
20 void NotifyWrapper(T obj
, Method m
, const Params
& p
) {
21 DispatchToMethod(base::internal::UnwrapTraits
<T
>::Unwrap(obj
), m
, p
);
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.
28 // Unlike regular ObserverList or ObserverListThreadSafe internal observer
29 // list is immutable (though not declared const) and cannot be modified after
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
{
37 typedef scoped_refptr
<base::SequencedTaskRunner
> TaskRunnerPtr
;
38 typedef std::map
<ObserverStoreType
, TaskRunnerPtr
> ObserversListMap
;
40 // Creates an empty list.
41 TaskRunnerBoundObserverList
<Observer
, ObserverStoreType
>() {}
43 // Creates a new list with given |observers|.
44 explicit TaskRunnerBoundObserverList
<Observer
, ObserverStoreType
>(
45 const ObserversListMap
& observers
)
46 : observers_(observers
) {}
48 virtual ~TaskRunnerBoundObserverList
<Observer
, ObserverStoreType
>() {}
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.
55 TaskRunnerBoundObserverList
<Observer
, ObserverStoreType
> AddObserver(
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
);
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
>
66 void Notify(Method method
, const Params
& params
) const {
68 (base::internal::ParamsUseScopedRefptrCorrectly
<Params
>::value
),
69 "bad unbound method params");
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
);
78 base::Bind(&NotifyWrapper
<ObserverStoreType
, Method
, Params
>,
79 it
->first
, method
, params
));
84 typedef base::internal::UnwrapTraits
<ObserverStoreType
> UnwrapTraits
;
86 ObserversListMap observers_
;
89 class FileAccessObserver
;
90 class FileChangeObserver
;
91 class FileUpdateObserver
;
93 typedef TaskRunnerBoundObserverList
<FileAccessObserver
> AccessObserverList
;
94 typedef TaskRunnerBoundObserverList
<FileChangeObserver
> ChangeObserverList
;
95 typedef TaskRunnerBoundObserverList
<FileUpdateObserver
> UpdateObserverList
;
97 } // namespace storage
99 #endif // STORAGE_BROWSER_FILEAPI_TASK_RUNNER_BOUND_OBSERVER_LIST_H_