1 // 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
5 #include "quiche/quic/test_tools/simulator/alarm_factory.h"
6
7 #include "absl/strings/str_format.h"
8 #include "quiche/quic/core/quic_alarm.h"
9
10 namespace quic {
11 namespace simulator {
12
13 // Alarm is an implementation of QuicAlarm which can schedule alarms in the
14 // simulation timeline.
15 class Alarm : public QuicAlarm {
16 public:
Alarm(Simulator * simulator,std::string name,QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)17 Alarm(Simulator* simulator, std::string name,
18 QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
19 : QuicAlarm(std::move(delegate)), adapter_(simulator, name, this) {}
~Alarm()20 ~Alarm() override {}
21
SetImpl()22 void SetImpl() override {
23 QUICHE_DCHECK(deadline().IsInitialized());
24 adapter_.Set(deadline());
25 }
26
CancelImpl()27 void CancelImpl() override { adapter_.Cancel(); }
28
29 private:
30 // An adapter class triggering a QuicAlarm using a simulation time system.
31 // An adapter is required here because neither Actor nor QuicAlarm are pure
32 // interfaces.
33 class Adapter : public Actor {
34 public:
Adapter(Simulator * simulator,std::string name,Alarm * parent)35 Adapter(Simulator* simulator, std::string name, Alarm* parent)
36 : Actor(simulator, name), parent_(parent) {}
~Adapter()37 ~Adapter() override {}
38
Set(QuicTime time)39 void Set(QuicTime time) { Schedule(std::max(time, clock_->Now())); }
Cancel()40 void Cancel() { Unschedule(); }
41
Act()42 void Act() override {
43 QUICHE_DCHECK(clock_->Now() >= parent_->deadline());
44 parent_->Fire();
45 }
46
47 private:
48 Alarm* parent_;
49 };
50 Adapter adapter_;
51 };
52
AlarmFactory(Simulator * simulator,std::string name)53 AlarmFactory::AlarmFactory(Simulator* simulator, std::string name)
54 : simulator_(simulator), name_(std::move(name)), counter_(0) {}
55
~AlarmFactory()56 AlarmFactory::~AlarmFactory() {}
57
GetNewAlarmName()58 std::string AlarmFactory::GetNewAlarmName() {
59 ++counter_;
60 return absl::StrFormat("%s (alarm %i)", name_, counter_);
61 }
62
CreateAlarm(QuicAlarm::Delegate * delegate)63 QuicAlarm* AlarmFactory::CreateAlarm(QuicAlarm::Delegate* delegate) {
64 return new Alarm(simulator_, GetNewAlarmName(),
65 QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
66 }
67
CreateAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,QuicConnectionArena * arena)68 QuicArenaScopedPtr<QuicAlarm> AlarmFactory::CreateAlarm(
69 QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
70 QuicConnectionArena* arena) {
71 if (arena != nullptr) {
72 return arena->New<Alarm>(simulator_, GetNewAlarmName(),
73 std::move(delegate));
74 }
75 return QuicArenaScopedPtr<QuicAlarm>(
76 new Alarm(simulator_, GetNewAlarmName(), std::move(delegate)));
77 }
78
79 } // namespace simulator
80 } // namespace quic
81