blob: 8ea3e589087bad3297b3ce7553aaf31804f9cdb1 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "quic/test_tools/simulator/alarm_factory.h"
#include "quic/core/quic_alarm.h"
#include "common/platform/api/quiche_str_cat.h"
namespace quic {
namespace simulator {
// Alarm is an implementation of QuicAlarm which can schedule alarms in the
// simulation timeline.
class Alarm : public QuicAlarm {
public:
Alarm(Simulator* simulator,
std::string name,
QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
: QuicAlarm(std::move(delegate)), adapter_(simulator, name, this) {}
~Alarm() override {}
void SetImpl() override {
DCHECK(deadline().IsInitialized());
adapter_.Set(deadline());
}
void CancelImpl() override { adapter_.Cancel(); }
private:
// An adapter class triggering a QuicAlarm using a simulation time system.
// An adapter is required here because neither Actor nor QuicAlarm are pure
// interfaces.
class Adapter : public Actor {
public:
Adapter(Simulator* simulator, std::string name, Alarm* parent)
: Actor(simulator, name), parent_(parent) {}
~Adapter() override {}
void Set(QuicTime time) { Schedule(std::max(time, clock_->Now())); }
void Cancel() { Unschedule(); }
void Act() override {
DCHECK(clock_->Now() >= parent_->deadline());
parent_->Fire();
}
private:
Alarm* parent_;
};
Adapter adapter_;
};
AlarmFactory::AlarmFactory(Simulator* simulator, std::string name)
: simulator_(simulator), name_(std::move(name)), counter_(0) {}
AlarmFactory::~AlarmFactory() {}
std::string AlarmFactory::GetNewAlarmName() {
++counter_;
return quiche::QuicheStringPrintf("%s (alarm %i)", name_.c_str(), counter_);
}
QuicAlarm* AlarmFactory::CreateAlarm(QuicAlarm::Delegate* delegate) {
return new Alarm(simulator_, GetNewAlarmName(),
QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
}
QuicArenaScopedPtr<QuicAlarm> AlarmFactory::CreateAlarm(
QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
QuicConnectionArena* arena) {
if (arena != nullptr) {
return arena->New<Alarm>(simulator_, GetNewAlarmName(),
std::move(delegate));
}
return QuicArenaScopedPtr<QuicAlarm>(
new Alarm(simulator_, GetNewAlarmName(), std::move(delegate)));
}
} // namespace simulator
} // namespace quic