Home | History | Annotate | Download | only in fileapi
      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 WEBKIT_BROWSER_FILEAPI_TASK_RUNNER_BOUND_OBSERVER_LIST_H_
      6 #define WEBKIT_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 fileapi {
     17 
     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);
     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)
     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.
     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>
     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 fileapi
     98 
     99 #endif  // WEBKIT_BROWSER_FILEAPI_TASK_RUNNER_BOUND_OBSERVER_LIST_H_
    100