blob: 0c7ef923b7a826634a1144d45b19198e4d3de633 [file] [log] [blame]
Avi Drissman64595482022-09-14 20:52:291// Copyright 2012 The Chromium Authors
rch16c74d1d2016-04-22 06:14:072// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ryan Hamiltona3ee93a72018-08-01 22:03:085#include "net/quic/quic_chromium_alarm_factory.h"
rch16c74d1d2016-04-22 06:14:076
Hans Wennborg0924470b2020-04-27 21:08:057#include "base/check.h"
Avi Drissman41c4a412023-01-11 22:45:378#include "base/functional/bind.h"
rch16c74d1d2016-04-22 06:14:079#include "base/location.h"
Keishi Hattori0e45c022021-11-27 09:25:5210#include "base/memory/raw_ptr.h"
Sean Mahere672a662023-01-09 21:42:2811#include "base/task/sequenced_task_runner.h"
Francois Dorayc30a2d02021-06-18 21:36:0112#include "base/time/tick_clock.h"
rch16c74d1d2016-04-22 06:14:0713#include "base/time/time.h"
Francois Dorayc30a2d02021-06-18 21:36:0114#include "base/timer/timer.h"
15#include "net/quic/platform/impl/quic_chromium_clock.h"
rch16c74d1d2016-04-22 06:14:0716
17namespace net {
18
19namespace {
20
Francois Dorayc30a2d02021-06-18 21:36:0121class QuicChromeAlarm : public quic::QuicAlarm, public base::TickClock {
rch16c74d1d2016-04-22 06:14:0722 public:
Ryan Hamilton8d9ee76e2018-05-29 23:52:5223 QuicChromeAlarm(const quic::QuicClock* clock,
Francois Dorayc30a2d02021-06-18 21:36:0124 base::SequencedTaskRunner* task_runner,
Ryan Hamilton8d9ee76e2018-05-29 23:52:5225 quic::QuicArenaScopedPtr<quic::QuicAlarm::Delegate> delegate)
26 : quic::QuicAlarm(std::move(delegate)),
rch16c74d1d2016-04-22 06:14:0727 clock_(clock),
Francois Dorayc30a2d02021-06-18 21:36:0128 // Unretained is safe because base::OneShotTimer never runs its task
29 // after being deleted.
30 on_alarm_callback_(base::BindRepeating(&QuicChromeAlarm::OnAlarm,
31 base::Unretained(this))),
32 timer_(std::make_unique<base::OneShotTimer>(this)) {
33 timer_->SetTaskRunner(task_runner);
34 }
rch16c74d1d2016-04-22 06:14:0735
36 protected:
37 void SetImpl() override {
38 DCHECK(deadline().IsInitialized());
Francois Dorayc30a2d02021-06-18 21:36:0139 const int64_t delay_us = (deadline() - clock_->Now()).ToMicroseconds();
Peter Kastinge5a38ed2021-10-02 03:06:3540 timer_->Start(FROM_HERE, base::Microseconds(delay_us), on_alarm_callback_);
rch16c74d1d2016-04-22 06:14:0741 }
42
43 void CancelImpl() override {
44 DCHECK(!deadline().IsInitialized());
Francois Dorayc30a2d02021-06-18 21:36:0145 timer_->Stop();
rch16c74d1d2016-04-22 06:14:0746 }
47
48 private:
49 void OnAlarm() {
Francois Dorayc30a2d02021-06-18 21:36:0150 DCHECK(deadline().IsInitialized());
rch16c74d1d2016-04-22 06:14:0751
Francois Dorayc30a2d02021-06-18 21:36:0152 // In tests, the time source used by the scheduler may not be in sync with
53 // |clock_|. Because of this, the scheduler may run this task when
54 // |clock->Now()| is smaller than |deadline()|. In that case, retry later.
55 // This shouldn't happen in production.
rch16c74d1d2016-04-22 06:14:0756 if (clock_->Now() < deadline()) {
57 SetImpl();
58 return;
59 }
60
Francois Dorayc30a2d02021-06-18 21:36:0161 DCHECK_LE(deadline(), clock_->Now());
rch16c74d1d2016-04-22 06:14:0762 Fire();
63 }
64
Francois Dorayc30a2d02021-06-18 21:36:0165 // base::TickClock:
66 base::TimeTicks NowTicks() const override {
67 return quic::QuicChromiumClock::QuicTimeToTimeTicks(clock_->Now());
68 }
69
Keishi Hattori0e45c022021-11-27 09:25:5270 const raw_ptr<const quic::QuicClock> clock_;
Francois Dorayc30a2d02021-06-18 21:36:0171 base::RepeatingClosure on_alarm_callback_;
72 const std::unique_ptr<base::OneShotTimer> timer_;
rch16c74d1d2016-04-22 06:14:0773};
74
75} // namespace
76
77QuicChromiumAlarmFactory::QuicChromiumAlarmFactory(
Francois Dorayc30a2d02021-06-18 21:36:0178 base::SequencedTaskRunner* task_runner,
Ryan Hamilton8d9ee76e2018-05-29 23:52:5279 const quic::QuicClock* clock)
Jeremy Romand54000b22019-07-08 18:40:1680 : task_runner_(task_runner), clock_(clock) {}
rch16c74d1d2016-04-22 06:14:0781
Tsuyoshi Horo07c3f0e2022-06-16 07:30:4782QuicChromiumAlarmFactory::~QuicChromiumAlarmFactory() = default;
rch16c74d1d2016-04-22 06:14:0783
Ryan Hamilton8d9ee76e2018-05-29 23:52:5284quic::QuicArenaScopedPtr<quic::QuicAlarm> QuicChromiumAlarmFactory::CreateAlarm(
85 quic::QuicArenaScopedPtr<quic::QuicAlarm::Delegate> delegate,
86 quic::QuicConnectionArena* arena) {
rch16c74d1d2016-04-22 06:14:0787 if (arena != nullptr) {
88 return arena->New<QuicChromeAlarm>(clock_, task_runner_,
89 std::move(delegate));
90 } else {
Ryan Hamilton8d9ee76e2018-05-29 23:52:5291 return quic::QuicArenaScopedPtr<quic::QuicAlarm>(
rch16c74d1d2016-04-22 06:14:0792 new QuicChromeAlarm(clock_, task_runner_, std::move(delegate)));
93 }
94}
95
Ryan Hamilton8d9ee76e2018-05-29 23:52:5296quic::QuicAlarm* QuicChromiumAlarmFactory::CreateAlarm(
97 quic::QuicAlarm::Delegate* delegate) {
98 return new QuicChromeAlarm(
99 clock_, task_runner_,
100 quic::QuicArenaScopedPtr<quic::QuicAlarm::Delegate>(delegate));
rch16c74d1d2016-04-22 06:14:07101}
102
103} // namespace net