1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Use of this source code is governed by a BSD-style license that can be 3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// found in the LICENSE file. 4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// OneShotTimer and RepeatingTimer provide a simple timer API. As the names 6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// suggest, OneShotTimer calls you back once after a time delay expires. 7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// RepeatingTimer on the other hand calls you back periodically with the 8b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// prescribed time interval. 9b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 10b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// OneShotTimer and RepeatingTimer both cancel the timer when they go out of 11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// scope, which makes it easy to ensure that you do not get called when your 12b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// object has gone out of scope. Just instantiate a OneShotTimer or 13b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// RepeatingTimer as a member variable of the class for which you wish to 14b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// receive timer events. 15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Sample RepeatingTimer usage: 17b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 18b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// class MyClass { 19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// public: 20b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// void StartDoingStuff() { 21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// timer_.Start(FROM_HERE, TimeDelta::FromSeconds(1), 22b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// this, &MyClass::DoStuff); 23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// } 24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// void StopDoingStuff() { 25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// timer_.Stop(); 26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// } 27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// private: 28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// void DoStuff() { 29b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// // This method is called every second to do stuff. 30b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// ... 31b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// } 32cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// base::RepeatingTimer timer_; 33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// }; 34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 35b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Both OneShotTimer and RepeatingTimer also support a Reset method, which 36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// allows you to easily defer the timer event until the timer delay passes once 37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// again. So, in the above example, if 0.5 seconds have already passed, 38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// calling Reset on timer_ would postpone DoStuff by another 1 second. In 39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// other words, Reset is shorthand for calling Stop and then Start again with 40b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// the same arguments. 41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// NOTE: These APIs are not thread safe. Always call from the same thread. 43b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#ifndef BASE_TIMER_TIMER_H_ 45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define BASE_TIMER_TIMER_H_ 46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 47b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// IMPORTANT: If you change timer code, make sure that all tests (including 48b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// disabled ones) from timer_unittests.cc pass locally. Some are disabled 49b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// because they're flaky on the buildbot, but when you run them locally you 50b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// should be able to tell the difference. 51b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 52b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/base_export.h" 53b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/bind.h" 54b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/bind_helpers.h" 55b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/callback.h" 56b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/location.h" 57cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/macros.h" 58b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/time/time.h" 59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base { 61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 62b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass BaseTimerTaskInternal; 63b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass SingleThreadTaskRunner; 64b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat//----------------------------------------------------------------------------- 66b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// This class wraps MessageLoop::PostDelayedTask to manage delayed and repeating 67b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// tasks. It must be destructed on the same thread that starts tasks. There are 68b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// DCHECKs in place to verify this. 69b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 70b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass BASE_EXPORT Timer { 71b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat public: 72b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Construct a timer in repeating or one-shot mode. Start or SetTaskInfo must 73b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // be called later to set task info. |retain_user_task| determines whether the 74b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // user_task is retained or reset when it runs or stops. 75b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Timer(bool retain_user_task, bool is_repeating); 76b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 77b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Construct a timer with retained task info. 78b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Timer(const tracked_objects::Location& posted_from, 79b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TimeDelta delay, 80b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const base::Closure& user_task, 81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool is_repeating); 82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat virtual ~Timer(); 84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Returns true if the timer is running (i.e., not stopped). 86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat virtual bool IsRunning() const; 87b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Returns the current delay for this timer. 89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat virtual TimeDelta GetCurrentDelay() const; 90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Set the task runner on which the task should be scheduled. This method can 92b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // only be called before any tasks have been scheduled. The task runner must 93b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // run tasks on the same thread the timer is used on. 94b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat virtual void SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner); 95b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 96b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Start the timer to run at the given |delay| from now. If the timer is 97b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // already running, it will be replaced to call the given |user_task|. 98b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat virtual void Start(const tracked_objects::Location& posted_from, 99b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TimeDelta delay, 100b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const base::Closure& user_task); 101b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 102b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Call this method to stop and cancel the timer. It is a no-op if the timer 103b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // is not running. 104b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat virtual void Stop(); 105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 106b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Call this method to reset the timer delay. The user_task_ must be set. If 107b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // the timer is not running, this will start it by posting a task. 108b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat virtual void Reset(); 109b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 110b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const base::Closure& user_task() const { return user_task_; } 111b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const TimeTicks& desired_run_time() const { return desired_run_time_; } 112b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 113b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat protected: 114b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Used to initiate a new delayed task. This has the side-effect of disabling 115b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // scheduled_task_ if it is non-null. 116b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void SetTaskInfo(const tracked_objects::Location& posted_from, 117b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TimeDelta delay, 118b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const base::Closure& user_task); 119b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 120b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void set_user_task(const Closure& task) { user_task_ = task; } 121b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void set_desired_run_time(TimeTicks desired) { desired_run_time_ = desired; } 122b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void set_is_running(bool running) { is_running_ = running; } 123b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 124b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const tracked_objects::Location& posted_from() const { return posted_from_; } 125b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool retain_user_task() const { return retain_user_task_; } 126b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool is_repeating() const { return is_repeating_; } 127b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool is_running() const { return is_running_; } 128b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 129b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat private: 130b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat friend class BaseTimerTaskInternal; 131b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 132b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Allocates a new scheduled_task_ and posts it on the current MessageLoop 133b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // with the given |delay|. scheduled_task_ must be NULL. scheduled_run_time_ 134b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // and desired_run_time_ are reset to Now() + delay. 135b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void PostNewScheduledTask(TimeDelta delay); 136b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 137b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Returns the task runner on which the task should be scheduled. If the 138b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // corresponding task_runner_ field is null, the task runner for the current 139b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // thread is returned. 140b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat scoped_refptr<SingleThreadTaskRunner> GetTaskRunner(); 141b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 142b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Disable scheduled_task_ and abandon it so that it no longer refers back to 143b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // this object. 144b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void AbandonScheduledTask(); 145b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 146b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Called by BaseTimerTaskInternal when the MessageLoop runs it. 147b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void RunScheduledTask(); 148b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 149b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Stop running task (if any) and abandon scheduled task (if any). 150b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void StopAndAbandon() { 151b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Stop(); 152b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat AbandonScheduledTask(); 153b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 154b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 155b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // When non-NULL, the scheduled_task_ is waiting in the MessageLoop to call 156b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // RunScheduledTask() at scheduled_run_time_. 157b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat BaseTimerTaskInternal* scheduled_task_; 158b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 159b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // The task runner on which the task should be scheduled. If it is null, the 160b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // task runner for the current thread should be used. 161b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat scoped_refptr<SingleThreadTaskRunner> task_runner_; 162b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 163b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Location in user code. 164b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat tracked_objects::Location posted_from_; 165b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Delay requested by user. 166b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TimeDelta delay_; 167b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // user_task_ is what the user wants to be run at desired_run_time_. 168b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat base::Closure user_task_; 169b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 170b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // The estimated time that the MessageLoop will run the scheduled_task_ that 171b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // will call RunScheduledTask(). This time can be a "zero" TimeTicks if the 172b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // task must be run immediately. 173b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TimeTicks scheduled_run_time_; 174b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 175b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // The desired run time of user_task_. The user may update this at any time, 176b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // even if their previous request has not run yet. If desired_run_time_ is 177b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // greater than scheduled_run_time_, a continuation task will be posted to 178b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // wait for the remaining time. This allows us to reuse the pending task so as 179b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // not to flood the MessageLoop with orphaned tasks when the user code 180b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // excessively Stops and Starts the timer. This time can be a "zero" TimeTicks 181b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // if the task must be run immediately. 182b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TimeTicks desired_run_time_; 183b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 184b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Thread ID of current MessageLoop for verifying single-threaded usage. 185b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int thread_id_; 186b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 187b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Repeating timers automatically post the task again before calling the task 188b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // callback. 189b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const bool is_repeating_; 190b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 191b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // If true, hold on to the user_task_ closure object for reuse. 192b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const bool retain_user_task_; 193b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 194b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // If true, user_task_ is scheduled to run sometime in the future. 195b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool is_running_; 196b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 197b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DISALLOW_COPY_AND_ASSIGN(Timer); 198b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}; 199b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 200b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat//----------------------------------------------------------------------------- 201b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// This class is an implementation detail of OneShotTimer and RepeatingTimer. 202b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Please do not use this class directly. 203b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass BaseTimerMethodPointer : public Timer { 204b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat public: 205b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // This is here to work around the fact that Timer::Start is "hidden" by the 206b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Start definition below, rather than being overloaded. 207b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // TODO(tim): We should remove uses of BaseTimerMethodPointer::Start below 208b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // and convert callers to use the base::Closure version in Timer::Start, 209b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // see bug 148832. 210b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat using Timer::Start; 211b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 212cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko enum RepeatMode { ONE_SHOT, REPEATING }; 213cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko BaseTimerMethodPointer(RepeatMode mode) 214cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko : Timer(mode == REPEATING, mode == REPEATING) {} 215b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 216b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Start the timer to run at the given |delay| from now. If the timer is 217b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // already running, it will be replaced to call a task formed from 218b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // |reviewer->*method|. 219cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko template <class Receiver> 220cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko void Start(const tracked_objects::Location& posted_from, 221cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko TimeDelta delay, 222cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko Receiver* receiver, 223cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko void (Receiver::*method)()) { 224b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Timer::Start(posted_from, delay, 225b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat base::Bind(method, base::Unretained(receiver))); 226b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 227b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}; 228b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 229b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat//----------------------------------------------------------------------------- 230b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// A simple, one-shot timer. See usage notes at the top of the file. 231cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass OneShotTimer : public BaseTimerMethodPointer { 232cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public: 233cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko OneShotTimer() : BaseTimerMethodPointer(ONE_SHOT) {} 234cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko}; 235b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 236b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat//----------------------------------------------------------------------------- 237b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// A simple, repeating timer. See usage notes at the top of the file. 238cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass RepeatingTimer : public BaseTimerMethodPointer { 239cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public: 240cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko RepeatingTimer() : BaseTimerMethodPointer(REPEATING) {} 241cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko}; 242b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 243b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat//----------------------------------------------------------------------------- 244b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// A Delay timer is like The Button from Lost. Once started, you have to keep 245b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// calling Reset otherwise it will call the given method in the MessageLoop 246b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// thread. 247b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 248b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Once created, it is inactive until Reset is called. Once |delay| seconds have 249b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// passed since the last call to Reset, the callback is made. Once the callback 250b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// has been made, it's inactive until Reset is called again. 251b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 252b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// If destroyed, the timeout is canceled and will not occur even if already 253b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// inflight. 254b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass DelayTimer : protected Timer { 255b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat public: 256cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko template <class Receiver> 257b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DelayTimer(const tracked_objects::Location& posted_from, 258b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat TimeDelta delay, 259b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Receiver* receiver, 260cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko void (Receiver::*method)()) 261cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko : Timer(posted_from, 262cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko delay, 263b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat base::Bind(method, base::Unretained(receiver)), 264b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat false) {} 265b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 266cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko void Reset() override; 267b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}; 268b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 269cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// This class has a templated method so it can not be exported without failing 270cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// to link in MSVC. But clang-plugin does not allow inline definitions of 271cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// virtual methods, so the inline definition lives in the header file here 272cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// to satisfy both. 273cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoinline void DelayTimer::Reset() { 274cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko Timer::Reset(); 275cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko} 276cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko 277b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace base 278b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 279b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif // BASE_TIMER_TIMER_H_ 280