106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Copyright (c) 2009 The Chromium Authors. All rights reserved.
206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Use of this source code is governed by a BSD-style license that can be
306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// found in the LICENSE file.
406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#ifndef CHROME_COMMON_WORKER_THREAD_TICKER_H_
606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#define CHROME_COMMON_WORKER_THREAD_TICKER_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include <vector>
1006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/synchronization/lock.h"
123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h"
1306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
1406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// This class provides the following functionality:
1506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// It invokes a set of registered handlers at periodic intervals in
1606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// the context of an arbitrary worker thread.
1706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// The timer runs on a separate thread, so it will run even if the current
1806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// thread is hung. Similarly, the callbacks will be called on a separate
1906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// thread so they won't block the main thread.
2006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochclass WorkerThreadTicker {
2106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch public:
2206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // This callback interface to be implemented by clients of this
2306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // class
2406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  class Callback {
2506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch   public:
2606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    // Gets invoked when the timer period is up
2706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    virtual void OnTick() = 0;
2806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
2906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch   protected:
3006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    virtual ~Callback() {}
3106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  };
3206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
3306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // tick_interval is the periodic interval in which to invoke the
3406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // registered handlers (in milliseconds)
3506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  explicit WorkerThreadTicker(int tick_interval);
3606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
3706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  ~WorkerThreadTicker();
3806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
3906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Registers a callback handler interface
4006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // tick_handler is the handler interface to register. The ownership of this
4106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // object is not transferred to this class.
4206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool RegisterTickHandler(Callback *tick_handler);
4306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
4406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Unregisters a callback handler interface
4506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // tick_handler is the handler interface to unregister
4606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool UnregisterTickHandler(Callback *tick_handler);
4706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
4806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Starts the ticker. Returns false if the ticker is already running
4906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // or if the Start fails.
5006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool Start();
5106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Stops the ticker and waits for all callbacks. to be done. This method
5206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // does not provide a way to stop without waiting for the callbacks to be
5306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // done because this is inherently risky.
5406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Returns false is the ticker is not running
5506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool Stop();
5606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool IsRunning() const {
5706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return is_running_;
5806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
5906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
6006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void set_tick_interval(int tick_interval) {
6106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    tick_interval_ = tick_interval;
6206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
6306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
6406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  int tick_interval() const {
6506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return tick_interval_;
6606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
6706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
6806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch private:
6906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  class TimerTask;
7006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
7106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void ScheduleTimerTask();
7206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
7306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // A list type that holds all registered callback interfaces
7406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  typedef std::vector<Callback*> TickHandlerListType;
7506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
7606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Lock to protect is_running_ and tick_handler_list_
7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::Lock lock_;
7806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
7906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  base::Thread timer_thread_;
8006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool is_running_;
8106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
8206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // The interval at which the callbacks are to be invoked
8306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  int tick_interval_;
8406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
8506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // A list that holds all registered callback interfaces
8606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  TickHandlerListType tick_handler_list_;
8706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
8806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  DISALLOW_COPY_AND_ASSIGN(WorkerThreadTicker);
8906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch};
9006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
9106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#endif  // CHROME_COMMON_WORKER_THREAD_TICKER_H_
92