xref: /aosp_15_r20/external/cronet/net/quic/quic_chromium_alarm_factory.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/quic/quic_chromium_alarm_factory.h"
6 
7 #include "base/check.h"
8 #include "base/functional/bind.h"
9 #include "base/location.h"
10 #include "base/memory/raw_ptr.h"
11 #include "base/task/sequenced_task_runner.h"
12 #include "base/time/tick_clock.h"
13 #include "base/time/time.h"
14 #include "base/timer/timer.h"
15 #include "net/quic/platform/impl/quic_chromium_clock.h"
16 
17 namespace net {
18 
19 namespace {
20 
21 class QuicChromeAlarm : public quic::QuicAlarm, public base::TickClock {
22  public:
QuicChromeAlarm(const quic::QuicClock * clock,scoped_refptr<base::SequencedTaskRunner> task_runner,quic::QuicArenaScopedPtr<quic::QuicAlarm::Delegate> delegate)23   QuicChromeAlarm(const quic::QuicClock* clock,
24                   scoped_refptr<base::SequencedTaskRunner> task_runner,
25                   quic::QuicArenaScopedPtr<quic::QuicAlarm::Delegate> delegate)
26       : quic::QuicAlarm(std::move(delegate)),
27         clock_(clock),
28         // 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(std::move(task_runner));
34   }
35 
36  protected:
SetImpl()37   void SetImpl() override {
38     DCHECK(deadline().IsInitialized());
39     const int64_t delay_us = (deadline() - clock_->Now()).ToMicroseconds();
40     timer_->Start(FROM_HERE, base::Microseconds(delay_us), on_alarm_callback_);
41   }
42 
CancelImpl()43   void CancelImpl() override {
44     DCHECK(!deadline().IsInitialized());
45     timer_->Stop();
46   }
47 
48  private:
OnAlarm()49   void OnAlarm() {
50     DCHECK(deadline().IsInitialized());
51 
52     // 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.
56     if (clock_->Now() < deadline()) {
57       SetImpl();
58       return;
59     }
60 
61     DCHECK_LE(deadline(), clock_->Now());
62     Fire();
63   }
64 
65   // base::TickClock:
NowTicks() const66   base::TimeTicks NowTicks() const override {
67     return quic::QuicChromiumClock::QuicTimeToTimeTicks(clock_->Now());
68   }
69 
70   const raw_ptr<const quic::QuicClock> clock_;
71   base::RepeatingClosure on_alarm_callback_;
72   const std::unique_ptr<base::OneShotTimer> timer_;
73 };
74 
75 }  // namespace
76 
QuicChromiumAlarmFactory(base::SequencedTaskRunner * task_runner,const quic::QuicClock * clock)77 QuicChromiumAlarmFactory::QuicChromiumAlarmFactory(
78     base::SequencedTaskRunner* task_runner,
79     const quic::QuicClock* clock)
80     : task_runner_(task_runner), clock_(clock) {}
81 
82 QuicChromiumAlarmFactory::~QuicChromiumAlarmFactory() = default;
83 
CreateAlarm(quic::QuicArenaScopedPtr<quic::QuicAlarm::Delegate> delegate,quic::QuicConnectionArena * arena)84 quic::QuicArenaScopedPtr<quic::QuicAlarm> QuicChromiumAlarmFactory::CreateAlarm(
85     quic::QuicArenaScopedPtr<quic::QuicAlarm::Delegate> delegate,
86     quic::QuicConnectionArena* arena) {
87   if (arena != nullptr) {
88     return arena->New<QuicChromeAlarm>(clock_, task_runner_,
89                                        std::move(delegate));
90   } else {
91     return quic::QuicArenaScopedPtr<quic::QuicAlarm>(
92         new QuicChromeAlarm(clock_, task_runner_, std::move(delegate)));
93   }
94 }
95 
CreateAlarm(quic::QuicAlarm::Delegate * delegate)96 quic::QuicAlarm* QuicChromiumAlarmFactory::CreateAlarm(
97     quic::QuicAlarm::Delegate* delegate) {
98   return new QuicChromeAlarm(
99       clock_, task_runner_,
100       quic::QuicArenaScopedPtr<quic::QuicAlarm::Delegate>(delegate));
101 }
102 
103 }  // namespace net
104