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 CHROME_COMMON_WORKER_THREAD_TICKER_H_
6#define CHROME_COMMON_WORKER_THREAD_TICKER_H_
7
8#include <vector>
9
10#include "base/synchronization/lock.h"
11#include "base/threading/thread.h"
12
13// This class provides the following functionality:
14// It invokes a set of registered handlers at periodic intervals in
15// the context of an arbitrary worker thread.
16// The timer runs on a separate thread, so it will run even if the current
17// thread is hung. Similarly, the callbacks will be called on a separate
18// thread so they won't block the main thread.
19class WorkerThreadTicker {
20 public:
21  // This callback interface to be implemented by clients of this
22  // class
23  class Callback {
24   public:
25    // Gets invoked when the timer period is up
26    virtual void OnTick() = 0;
27
28   protected:
29    virtual ~Callback() {}
30  };
31
32  // tick_interval is the periodic interval in which to invoke the
33  // registered handlers (in milliseconds)
34  explicit WorkerThreadTicker(int tick_interval);
35
36  ~WorkerThreadTicker();
37
38  // Registers a callback handler interface
39  // tick_handler is the handler interface to register. The ownership of this
40  // object is not transferred to this class.
41  bool RegisterTickHandler(Callback *tick_handler);
42
43  // Unregisters a callback handler interface
44  // tick_handler is the handler interface to unregister
45  bool UnregisterTickHandler(Callback *tick_handler);
46
47  // Starts the ticker. Returns false if the ticker is already running
48  // or if the Start fails.
49  bool Start();
50  // Stops the ticker and waits for all callbacks. to be done. This method
51  // does not provide a way to stop without waiting for the callbacks to be
52  // done because this is inherently risky.
53  // Returns false is the ticker is not running
54  bool Stop();
55  bool IsRunning() const {
56    return is_running_;
57  }
58
59  void set_tick_interval(int tick_interval) {
60    tick_interval_ = base::TimeDelta::FromMilliseconds(tick_interval);
61  }
62
63  int tick_interval() const {
64    return tick_interval_.InMilliseconds();
65  }
66
67 private:
68  void ScheduleTimerTask();
69
70  void TimerTask();
71
72  // A list type that holds all registered callback interfaces
73  typedef std::vector<Callback*> TickHandlerListType;
74
75  // Lock to protect is_running_ and tick_handler_list_
76  base::Lock lock_;
77
78  base::Thread timer_thread_;
79  bool is_running_;
80
81  // The interval at which the callbacks are to be invoked
82  base::TimeDelta tick_interval_;
83
84  // A list that holds all registered callback interfaces
85  TickHandlerListType tick_handler_list_;
86
87  DISALLOW_COPY_AND_ASSIGN(WorkerThreadTicker);
88};
89
90#endif  // CHROME_COMMON_WORKER_THREAD_TICKER_H_
91