blob: 65561ac6868abf412d599037f5475d219461cae9 [file] [log] [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_TIMER_WALL_CLOCK_TIMER_H_
#define BASE_TIMER_WALL_CLOCK_TIMER_H_
#include "base/base_export.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/power_monitor/power_observer.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
namespace base {
class Clock;
class TickClock;
// `WallClockTimer` is based on `OneShotTimer` and provides a similar API.
// Where `OneShotTimer` uses `TimeTicks`, however, `WallClockTimer` uses `Time`.
// On some platforms, `TimeTicks` freezes during suspend; `Time` does not.
// `WallClockTimer` recomputes the desired delay after resuming from suspend, so
// on these platforms, suspends will "delay" `OneShotTimer` but not
// `WallClockTimer`.
//
// This does not attempt to observe and accommodate other `Time` changes, e.g.
// `Time` moving backwards in response to a DST change. `WallClockTimer` will
// only notice such changes if the system is subsequently suspended (which will
// cause a recalculation on resume that will coincidentally take them into
// account).
//
// After construction, the timer will become bound to the first sequence any
// method is called on. All subsequent calls must happen on that sequence until
// the task runs or is canceled via `Stop()`, after which the timer may be
// destroyed or restarted on another sequence.
class BASE_EXPORT WallClockTimer : public PowerSuspendObserver {
public:
// Constructs a timer. Start() must be called later to start the timer.
// If |clock| is provided, it's used instead of
// DefaultClock::GetInstance() to calulate timer's delay. If |tick_clock|
// is provided, it's used instead of TimeTicks::Now() to get TimeTicks when
// scheduling tasks.
WallClockTimer();
WallClockTimer(const Clock* clock, const TickClock* tick_clock);
WallClockTimer(const WallClockTimer&) = delete;
WallClockTimer& operator=(const WallClockTimer&) = delete;
~WallClockTimer() override;
// Starts the timer to run at the given |desired_run_time|. If the timer is
// already running, it will be replaced to call the given |user_task|.
virtual void Start(const Location& posted_from,
Time desired_run_time,
OnceClosure user_task);
// Starts the timer to run at the given |desired_run_time|. If the timer is
// already running, it will be replaced to call a task formed from
// |receiver|->*|method|.
template <class Receiver>
void Start(const Location& posted_from,
Time desired_run_time,
Receiver* receiver,
void (Receiver::*method)()) {
Start(posted_from, desired_run_time,
BindOnce(method, Unretained(receiver)));
}
// Stops the timer. No-op if the timer is not running.
void Stop();
// Returns whether the timer is running.
bool IsRunning() const;
// PowerSuspendObserver:
void OnResume() override;
Time desired_run_time() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return desired_run_time_;
}
private:
void RunUserTask();
SEQUENCE_CHECKER(sequence_checker_);
// Location in user code.
Location posted_from_ GUARDED_BY_CONTEXT(sequence_checker_);
// The desired run time of |user_task_|.
Time desired_run_time_ GUARDED_BY_CONTEXT(sequence_checker_);
OnceClosure user_task_ GUARDED_BY_CONTEXT(sequence_checker_);
OneShotTimer timer_;
// The clock used to calculate the run time for scheduled tasks.
const raw_ptr<const Clock> clock_;
};
} // namespace base
#endif // BASE_TIMER_WALL_CLOCK_TIMER_H_