blob: e70fdf70e721b8ddce34cfc1c52c92c91d78e881 [file] [log] [blame]
rch16c74d1d2016-04-22 06:14:071// 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
Ryan Hamiltona3ee93a72018-08-01 22:03:085#include "net/quic/quic_chromium_alarm_factory.h"
rch16c74d1d2016-04-22 06:14:076
7#include "base/bind.h"
Hans Wennborg0924470b2020-04-27 21:08:058#include "base/check.h"
rch16c74d1d2016-04-22 06:14:079#include "base/location.h"
Keishi Hattori0e45c022021-11-27 09:25:5210#include "base/memory/raw_ptr.h"
Francois Dorayc30a2d02021-06-18 21:36:0111#include "base/time/tick_clock.h"
rch16c74d1d2016-04-22 06:14:0712#include "base/time/time.h"
Francois Dorayc30a2d02021-06-18 21:36:0113#include "base/timer/timer.h"
14#include "net/quic/platform/impl/quic_chromium_clock.h"
rch16c74d1d2016-04-22 06:14:0715
16namespace net {
17
18namespace {
19
Francois Dorayc30a2d02021-06-18 21:36:0120class QuicChromeAlarm : public quic::QuicAlarm, public base::TickClock {
rch16c74d1d2016-04-22 06:14:0721 public:
Ryan Hamilton8d9ee76e2018-05-29 23:52:5222 QuicChromeAlarm(const quic::QuicClock* clock,
Francois Dorayc30a2d02021-06-18 21:36:0123 base::SequencedTaskRunner* task_runner,
Ryan Hamilton8d9ee76e2018-05-29 23:52:5224 quic::QuicArenaScopedPtr<quic::QuicAlarm::Delegate> delegate)
25 : quic::QuicAlarm(std::move(delegate)),
rch16c74d1d2016-04-22 06:14:0726 clock_(clock),
Francois Dorayc30a2d02021-06-18 21:36:0127 // Unretained is safe because base::OneShotTimer never runs its task
28 // after being deleted.
29 on_alarm_callback_(base::BindRepeating(&QuicChromeAlarm::OnAlarm,
30 base::Unretained(this))),
31 timer_(std::make_unique<base::OneShotTimer>(this)) {
32 timer_->SetTaskRunner(task_runner);
33 }
rch16c74d1d2016-04-22 06:14:0734
35 protected:
36 void SetImpl() override {
37 DCHECK(deadline().IsInitialized());
Francois Dorayc30a2d02021-06-18 21:36:0138 const int64_t delay_us = (deadline() - clock_->Now()).ToMicroseconds();
Peter Kastinge5a38ed2021-10-02 03:06:3539 timer_->Start(FROM_HERE, base::Microseconds(delay_us), on_alarm_callback_);
rch16c74d1d2016-04-22 06:14:0740 }
41
42 void CancelImpl() override {
43 DCHECK(!deadline().IsInitialized());
Francois Dorayc30a2d02021-06-18 21:36:0144 timer_->Stop();
rch16c74d1d2016-04-22 06:14:0745 }
46
47 private:
48 void OnAlarm() {
Francois Dorayc30a2d02021-06-18 21:36:0149 DCHECK(deadline().IsInitialized());
rch16c74d1d2016-04-22 06:14:0750
Francois Dorayc30a2d02021-06-18 21:36:0151 // In tests, the time source used by the scheduler may not be in sync with
52 // |clock_|. Because of this, the scheduler may run this task when
53 // |clock->Now()| is smaller than |deadline()|. In that case, retry later.
54 // This shouldn't happen in production.
rch16c74d1d2016-04-22 06:14:0755 if (clock_->Now() < deadline()) {
56 SetImpl();
57 return;
58 }
59
Francois Dorayc30a2d02021-06-18 21:36:0160 DCHECK_LE(deadline(), clock_->Now());
rch16c74d1d2016-04-22 06:14:0761 Fire();
62 }
63
Francois Dorayc30a2d02021-06-18 21:36:0164 // base::TickClock:
65 base::TimeTicks NowTicks() const override {
66 return quic::QuicChromiumClock::QuicTimeToTimeTicks(clock_->Now());
67 }
68
Keishi Hattori0e45c022021-11-27 09:25:5269 const raw_ptr<const quic::QuicClock> clock_;
Francois Dorayc30a2d02021-06-18 21:36:0170 base::RepeatingClosure on_alarm_callback_;
71 const std::unique_ptr<base::OneShotTimer> timer_;
rch16c74d1d2016-04-22 06:14:0772};
73
74} // namespace
75
76QuicChromiumAlarmFactory::QuicChromiumAlarmFactory(
Francois Dorayc30a2d02021-06-18 21:36:0177 base::SequencedTaskRunner* task_runner,
Ryan Hamilton8d9ee76e2018-05-29 23:52:5278 const quic::QuicClock* clock)
Jeremy Romand54000b22019-07-08 18:40:1679 : task_runner_(task_runner), clock_(clock) {}
rch16c74d1d2016-04-22 06:14:0780
Tsuyoshi Horo07c3f0e2022-06-16 07:30:4781QuicChromiumAlarmFactory::~QuicChromiumAlarmFactory() = default;
rch16c74d1d2016-04-22 06:14:0782
Ryan Hamilton8d9ee76e2018-05-29 23:52:5283quic::QuicArenaScopedPtr<quic::QuicAlarm> QuicChromiumAlarmFactory::CreateAlarm(
84 quic::QuicArenaScopedPtr<quic::QuicAlarm::Delegate> delegate,
85 quic::QuicConnectionArena* arena) {
rch16c74d1d2016-04-22 06:14:0786 if (arena != nullptr) {
87 return arena->New<QuicChromeAlarm>(clock_, task_runner_,
88 std::move(delegate));
89 } else {
Ryan Hamilton8d9ee76e2018-05-29 23:52:5290 return quic::QuicArenaScopedPtr<quic::QuicAlarm>(
rch16c74d1d2016-04-22 06:14:0791 new QuicChromeAlarm(clock_, task_runner_, std::move(delegate)));
92 }
93}
94
Ryan Hamilton8d9ee76e2018-05-29 23:52:5295quic::QuicAlarm* QuicChromiumAlarmFactory::CreateAlarm(
96 quic::QuicAlarm::Delegate* delegate) {
97 return new QuicChromeAlarm(
98 clock_, task_runner_,
99 quic::QuicArenaScopedPtr<quic::QuicAlarm::Delegate>(delegate));
rch16c74d1d2016-04-22 06:14:07100}
101
102} // namespace net