dcsctp: Convert timers to rtc::TimeDelta
With this, the code base should be mostly converted from using DurationMs to rtc::TimeDelta, and the work can continue to replace TimeMs with rtc::Timestamp. Bug: webrtc:15593 Change-Id: I083fee6eccb173efc0232bb8d46e2554a5fbee5b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/326161 Reviewed-by: Florent Castelli <orphis@webrtc.org> Commit-Queue: Victor Boivie <boivie@webrtc.org> Cr-Commit-Position: refs/heads/main@{#41101}
This commit is contained in:
parent
644025c51f
commit
4397482d71
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
namespace dcsctp {
|
namespace dcsctp {
|
||||||
namespace {
|
namespace {
|
||||||
|
using ::webrtc::TimeDelta;
|
||||||
using ::testing::ElementsAre;
|
using ::testing::ElementsAre;
|
||||||
using ::testing::IsEmpty;
|
using ::testing::IsEmpty;
|
||||||
using ::testing::SizeIs;
|
using ::testing::SizeIs;
|
||||||
@ -42,8 +43,8 @@ class DataTrackerTest : public testing::Test {
|
|||||||
}),
|
}),
|
||||||
timer_(timer_manager_.CreateTimer(
|
timer_(timer_manager_.CreateTimer(
|
||||||
"test/delayed_ack",
|
"test/delayed_ack",
|
||||||
[]() { return DurationMs(0); },
|
[]() { return TimeDelta::Zero(); },
|
||||||
TimerOptions(DurationMs(0)))),
|
TimerOptions(TimeDelta::Zero()))),
|
||||||
tracker_(
|
tracker_(
|
||||||
std::make_unique<DataTracker>("log: ", timer_.get(), kInitialTSN)) {
|
std::make_unique<DataTracker>("log: ", timer_.get(), kInitialTSN)) {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import("../../../webrtc.gni")
|
|||||||
rtc_source_set("context") {
|
rtc_source_set("context") {
|
||||||
sources = [ "context.h" ]
|
sources = [ "context.h" ]
|
||||||
deps = [
|
deps = [
|
||||||
|
"../../../api/units:time_delta",
|
||||||
"../common:internal_types",
|
"../common:internal_types",
|
||||||
"../packet:sctp_packet",
|
"../packet:sctp_packet",
|
||||||
"../public:socket",
|
"../public:socket",
|
||||||
@ -24,6 +25,7 @@ rtc_library("heartbeat_handler") {
|
|||||||
":context",
|
":context",
|
||||||
"../../../api:array_view",
|
"../../../api:array_view",
|
||||||
"../../../rtc_base:checks",
|
"../../../rtc_base:checks",
|
||||||
|
"../../../api/units:time_delta",
|
||||||
"../../../rtc_base:logging",
|
"../../../rtc_base:logging",
|
||||||
"../packet:bounded_io",
|
"../packet:bounded_io",
|
||||||
"../packet:chunk",
|
"../packet:chunk",
|
||||||
@ -48,6 +50,7 @@ rtc_library("stream_reset_handler") {
|
|||||||
deps = [
|
deps = [
|
||||||
":context",
|
":context",
|
||||||
"../../../api:array_view",
|
"../../../api:array_view",
|
||||||
|
"../../../api/units:time_delta",
|
||||||
"../../../rtc_base:checks",
|
"../../../rtc_base:checks",
|
||||||
"../../../rtc_base:logging",
|
"../../../rtc_base:logging",
|
||||||
"../../../rtc_base/containers:flat_set",
|
"../../../rtc_base/containers:flat_set",
|
||||||
@ -96,6 +99,7 @@ rtc_library("transmission_control_block") {
|
|||||||
":packet_sender",
|
":packet_sender",
|
||||||
":stream_reset_handler",
|
":stream_reset_handler",
|
||||||
"../../../api:array_view",
|
"../../../api:array_view",
|
||||||
|
"../../../api/units:time_delta",
|
||||||
"../../../api/task_queue:task_queue",
|
"../../../api/task_queue:task_queue",
|
||||||
"../../../rtc_base:checks",
|
"../../../rtc_base:checks",
|
||||||
"../../../rtc_base:logging",
|
"../../../rtc_base:logging",
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
|
#include "api/units/time_delta.h"
|
||||||
#include "net/dcsctp/common/internal_types.h"
|
#include "net/dcsctp/common/internal_types.h"
|
||||||
#include "net/dcsctp/packet/sctp_packet.h"
|
#include "net/dcsctp/packet/sctp_packet.h"
|
||||||
#include "net/dcsctp/public/dcsctp_socket.h"
|
#include "net/dcsctp/public/dcsctp_socket.h"
|
||||||
|
|||||||
@ -82,6 +82,7 @@
|
|||||||
|
|
||||||
namespace dcsctp {
|
namespace dcsctp {
|
||||||
namespace {
|
namespace {
|
||||||
|
using ::webrtc::TimeDelta;
|
||||||
|
|
||||||
// https://tools.ietf.org/html/rfc4960#section-5.1
|
// https://tools.ietf.org/html/rfc4960#section-5.1
|
||||||
constexpr uint32_t kMinVerificationTag = 1;
|
constexpr uint32_t kMinVerificationTag = 1;
|
||||||
@ -187,19 +188,19 @@ DcSctpSocket::DcSctpSocket(absl::string_view log_prefix,
|
|||||||
t1_init_(timer_manager_.CreateTimer(
|
t1_init_(timer_manager_.CreateTimer(
|
||||||
"t1-init",
|
"t1-init",
|
||||||
absl::bind_front(&DcSctpSocket::OnInitTimerExpiry, this),
|
absl::bind_front(&DcSctpSocket::OnInitTimerExpiry, this),
|
||||||
TimerOptions(options.t1_init_timeout,
|
TimerOptions(options.t1_init_timeout.ToTimeDelta(),
|
||||||
TimerBackoffAlgorithm::kExponential,
|
TimerBackoffAlgorithm::kExponential,
|
||||||
options.max_init_retransmits))),
|
options.max_init_retransmits))),
|
||||||
t1_cookie_(timer_manager_.CreateTimer(
|
t1_cookie_(timer_manager_.CreateTimer(
|
||||||
"t1-cookie",
|
"t1-cookie",
|
||||||
absl::bind_front(&DcSctpSocket::OnCookieTimerExpiry, this),
|
absl::bind_front(&DcSctpSocket::OnCookieTimerExpiry, this),
|
||||||
TimerOptions(options.t1_cookie_timeout,
|
TimerOptions(options.t1_cookie_timeout.ToTimeDelta(),
|
||||||
TimerBackoffAlgorithm::kExponential,
|
TimerBackoffAlgorithm::kExponential,
|
||||||
options.max_init_retransmits))),
|
options.max_init_retransmits))),
|
||||||
t2_shutdown_(timer_manager_.CreateTimer(
|
t2_shutdown_(timer_manager_.CreateTimer(
|
||||||
"t2-shutdown",
|
"t2-shutdown",
|
||||||
absl::bind_front(&DcSctpSocket::OnShutdownTimerExpiry, this),
|
absl::bind_front(&DcSctpSocket::OnShutdownTimerExpiry, this),
|
||||||
TimerOptions(options.t2_shutdown_timeout,
|
TimerOptions(options.t2_shutdown_timeout.ToTimeDelta(),
|
||||||
TimerBackoffAlgorithm::kExponential,
|
TimerBackoffAlgorithm::kExponential,
|
||||||
options.max_retransmissions))),
|
options.max_retransmissions))),
|
||||||
packet_sender_(callbacks_,
|
packet_sender_(callbacks_,
|
||||||
@ -631,7 +632,7 @@ void DcSctpSocket::MaybeSendShutdownOnPacketReceived(const SctpPacket& packet) {
|
|||||||
// respond to each received packet containing one or more DATA chunks with
|
// respond to each received packet containing one or more DATA chunks with
|
||||||
// a SHUTDOWN chunk and restart the T2-shutdown timer.""
|
// a SHUTDOWN chunk and restart the T2-shutdown timer.""
|
||||||
SendShutdown();
|
SendShutdown();
|
||||||
t2_shutdown_->set_duration(DurationMs(tcb_->current_rto()));
|
t2_shutdown_->set_duration(tcb_->current_rto());
|
||||||
t2_shutdown_->Start();
|
t2_shutdown_->Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -921,7 +922,7 @@ bool DcSctpSocket::HandleUnrecognizedChunk(
|
|||||||
return continue_processing;
|
return continue_processing;
|
||||||
}
|
}
|
||||||
|
|
||||||
DurationMs DcSctpSocket::OnInitTimerExpiry() {
|
TimeDelta DcSctpSocket::OnInitTimerExpiry() {
|
||||||
RTC_DLOG(LS_VERBOSE) << log_prefix() << "Timer " << t1_init_->name()
|
RTC_DLOG(LS_VERBOSE) << log_prefix() << "Timer " << t1_init_->name()
|
||||||
<< " has expired: " << t1_init_->expiration_count()
|
<< " has expired: " << t1_init_->expiration_count()
|
||||||
<< "/" << t1_init_->options().max_restarts.value_or(-1);
|
<< "/" << t1_init_->options().max_restarts.value_or(-1);
|
||||||
@ -933,10 +934,10 @@ DurationMs DcSctpSocket::OnInitTimerExpiry() {
|
|||||||
InternalClose(ErrorKind::kTooManyRetries, "No INIT_ACK received");
|
InternalClose(ErrorKind::kTooManyRetries, "No INIT_ACK received");
|
||||||
}
|
}
|
||||||
RTC_DCHECK(IsConsistent());
|
RTC_DCHECK(IsConsistent());
|
||||||
return DurationMs(0);
|
return TimeDelta::Zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
DurationMs DcSctpSocket::OnCookieTimerExpiry() {
|
TimeDelta DcSctpSocket::OnCookieTimerExpiry() {
|
||||||
// https://tools.ietf.org/html/rfc4960#section-4
|
// https://tools.ietf.org/html/rfc4960#section-4
|
||||||
// "If the T1-cookie timer expires, the endpoint MUST retransmit COOKIE
|
// "If the T1-cookie timer expires, the endpoint MUST retransmit COOKIE
|
||||||
// ECHO and restart the T1-cookie timer without changing state. This MUST
|
// ECHO and restart the T1-cookie timer without changing state. This MUST
|
||||||
@ -957,10 +958,10 @@ DurationMs DcSctpSocket::OnCookieTimerExpiry() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RTC_DCHECK(IsConsistent());
|
RTC_DCHECK(IsConsistent());
|
||||||
return DurationMs(0);
|
return TimeDelta::Zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
DurationMs DcSctpSocket::OnShutdownTimerExpiry() {
|
TimeDelta DcSctpSocket::OnShutdownTimerExpiry() {
|
||||||
RTC_DLOG(LS_VERBOSE) << log_prefix() << "Timer " << t2_shutdown_->name()
|
RTC_DLOG(LS_VERBOSE) << log_prefix() << "Timer " << t2_shutdown_->name()
|
||||||
<< " has expired: " << t2_shutdown_->expiration_count()
|
<< " has expired: " << t2_shutdown_->expiration_count()
|
||||||
<< "/"
|
<< "/"
|
||||||
@ -980,7 +981,7 @@ DurationMs DcSctpSocket::OnShutdownTimerExpiry() {
|
|||||||
|
|
||||||
InternalClose(ErrorKind::kTooManyRetries, "No SHUTDOWN_ACK received");
|
InternalClose(ErrorKind::kTooManyRetries, "No SHUTDOWN_ACK received");
|
||||||
RTC_DCHECK(IsConsistent());
|
RTC_DCHECK(IsConsistent());
|
||||||
return DurationMs(0);
|
return TimeDelta::Zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://tools.ietf.org/html/rfc4960#section-9.2
|
// https://tools.ietf.org/html/rfc4960#section-9.2
|
||||||
@ -988,7 +989,7 @@ DurationMs DcSctpSocket::OnShutdownTimerExpiry() {
|
|||||||
// updated last sequential TSN received from its peer."
|
// updated last sequential TSN received from its peer."
|
||||||
SendShutdown();
|
SendShutdown();
|
||||||
RTC_DCHECK(IsConsistent());
|
RTC_DCHECK(IsConsistent());
|
||||||
return DurationMs(tcb_->current_rto());
|
return tcb_->current_rto();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DcSctpSocket::OnSentPacket(rtc::ArrayView<const uint8_t> packet,
|
void DcSctpSocket::OnSentPacket(rtc::ArrayView<const uint8_t> packet,
|
||||||
@ -1731,7 +1732,7 @@ void DcSctpSocket::MaybeSendShutdownOrAck() {
|
|||||||
// state.""
|
// state.""
|
||||||
|
|
||||||
SendShutdown();
|
SendShutdown();
|
||||||
t2_shutdown_->set_duration(DurationMs(tcb_->current_rto()));
|
t2_shutdown_->set_duration(tcb_->current_rto());
|
||||||
t2_shutdown_->Start();
|
t2_shutdown_->Start();
|
||||||
SetState(State::kShutdownSent, "No more outstanding data");
|
SetState(State::kShutdownSent, "No more outstanding data");
|
||||||
} else if (state_ == State::kShutdownReceived) {
|
} else if (state_ == State::kShutdownReceived) {
|
||||||
@ -1754,7 +1755,7 @@ void DcSctpSocket::SendShutdown() {
|
|||||||
|
|
||||||
void DcSctpSocket::SendShutdownAck() {
|
void DcSctpSocket::SendShutdownAck() {
|
||||||
packet_sender_.Send(tcb_->PacketBuilder().Add(ShutdownAckChunk()));
|
packet_sender_.Send(tcb_->PacketBuilder().Add(ShutdownAckChunk()));
|
||||||
t2_shutdown_->set_duration(DurationMs(tcb_->current_rto()));
|
t2_shutdown_->set_duration(tcb_->current_rto());
|
||||||
t2_shutdown_->Start();
|
t2_shutdown_->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -155,9 +155,9 @@ class DcSctpSocket : public DcSctpSocketInterface {
|
|||||||
// Closes the association, because of too many retransmission errors.
|
// Closes the association, because of too many retransmission errors.
|
||||||
void CloseConnectionBecauseOfTooManyTransmissionErrors();
|
void CloseConnectionBecauseOfTooManyTransmissionErrors();
|
||||||
// Timer expiration handlers
|
// Timer expiration handlers
|
||||||
DurationMs OnInitTimerExpiry();
|
webrtc::TimeDelta OnInitTimerExpiry();
|
||||||
DurationMs OnCookieTimerExpiry();
|
webrtc::TimeDelta OnCookieTimerExpiry();
|
||||||
DurationMs OnShutdownTimerExpiry();
|
webrtc::TimeDelta OnShutdownTimerExpiry();
|
||||||
void OnSentPacket(rtc::ArrayView<const uint8_t> packet,
|
void OnSentPacket(rtc::ArrayView<const uint8_t> packet,
|
||||||
SendPacketStatus status);
|
SendPacketStatus status);
|
||||||
// Sends SHUTDOWN or SHUTDOWN-ACK if the socket is shutting down and if all
|
// Sends SHUTDOWN or SHUTDOWN-ACK if the socket is shutting down and if all
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
|
#include "api/units/time_delta.h"
|
||||||
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
#include "net/dcsctp/packet/bounded_byte_reader.h"
|
||||||
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
#include "net/dcsctp/packet/bounded_byte_writer.h"
|
||||||
#include "net/dcsctp/packet/chunk/heartbeat_ack_chunk.h"
|
#include "net/dcsctp/packet/chunk/heartbeat_ack_chunk.h"
|
||||||
@ -35,6 +36,7 @@
|
|||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
|
|
||||||
namespace dcsctp {
|
namespace dcsctp {
|
||||||
|
using ::webrtc::TimeDelta;
|
||||||
|
|
||||||
// This is stored (in serialized form) as HeartbeatInfoParameter sent in
|
// This is stored (in serialized form) as HeartbeatInfoParameter sent in
|
||||||
// HeartbeatRequestChunk and received back in HeartbeatAckChunk. It should be
|
// HeartbeatRequestChunk and received back in HeartbeatAckChunk. It should be
|
||||||
@ -97,12 +99,12 @@ HeartbeatHandler::HeartbeatHandler(absl::string_view log_prefix,
|
|||||||
interval_timer_(timer_manager_->CreateTimer(
|
interval_timer_(timer_manager_->CreateTimer(
|
||||||
"heartbeat-interval",
|
"heartbeat-interval",
|
||||||
absl::bind_front(&HeartbeatHandler::OnIntervalTimerExpiry, this),
|
absl::bind_front(&HeartbeatHandler::OnIntervalTimerExpiry, this),
|
||||||
TimerOptions(DurationMs(interval_duration_),
|
TimerOptions(interval_duration_,
|
||||||
TimerBackoffAlgorithm::kFixed))),
|
TimerBackoffAlgorithm::kFixed))),
|
||||||
timeout_timer_(timer_manager_->CreateTimer(
|
timeout_timer_(timer_manager_->CreateTimer(
|
||||||
"heartbeat-timeout",
|
"heartbeat-timeout",
|
||||||
absl::bind_front(&HeartbeatHandler::OnTimeoutTimerExpiry, this),
|
absl::bind_front(&HeartbeatHandler::OnTimeoutTimerExpiry, this),
|
||||||
TimerOptions(options.rto_initial,
|
TimerOptions(options.rto_initial.ToTimeDelta(),
|
||||||
TimerBackoffAlgorithm::kExponential,
|
TimerBackoffAlgorithm::kExponential,
|
||||||
/*max_restarts=*/0))) {
|
/*max_restarts=*/0))) {
|
||||||
// The interval timer must always be running as long as the association is up.
|
// The interval timer must always be running as long as the association is up.
|
||||||
@ -119,9 +121,9 @@ void HeartbeatHandler::RestartTimer() {
|
|||||||
// The RTT should be used, but it's not easy accessible. The RTO will
|
// The RTT should be used, but it's not easy accessible. The RTO will
|
||||||
// suffice.
|
// suffice.
|
||||||
interval_timer_->set_duration(
|
interval_timer_->set_duration(
|
||||||
DurationMs(interval_duration_ + ctx_->current_rto()));
|
interval_duration_ + ctx_->current_rto());
|
||||||
} else {
|
} else {
|
||||||
interval_timer_->set_duration(DurationMs(interval_duration_));
|
interval_timer_->set_duration(interval_duration_);
|
||||||
}
|
}
|
||||||
|
|
||||||
interval_timer_->Start();
|
interval_timer_->Start();
|
||||||
@ -166,13 +168,13 @@ void HeartbeatHandler::HandleHeartbeatAck(HeartbeatAckChunk chunk) {
|
|||||||
ctx_->ClearTxErrorCounter();
|
ctx_->ClearTxErrorCounter();
|
||||||
}
|
}
|
||||||
|
|
||||||
DurationMs HeartbeatHandler::OnIntervalTimerExpiry() {
|
TimeDelta HeartbeatHandler::OnIntervalTimerExpiry() {
|
||||||
if (ctx_->is_connection_established()) {
|
if (ctx_->is_connection_established()) {
|
||||||
HeartbeatInfo info(ctx_->callbacks().TimeMillis());
|
HeartbeatInfo info(ctx_->callbacks().TimeMillis());
|
||||||
timeout_timer_->set_duration(DurationMs(ctx_->current_rto()));
|
timeout_timer_->set_duration(ctx_->current_rto());
|
||||||
timeout_timer_->Start();
|
timeout_timer_->Start();
|
||||||
RTC_DLOG(LS_INFO) << log_prefix_ << "Sending HEARTBEAT with timeout "
|
RTC_DLOG(LS_INFO) << log_prefix_ << "Sending HEARTBEAT with timeout "
|
||||||
<< *timeout_timer_->duration();
|
<< webrtc::ToString(timeout_timer_->duration());
|
||||||
|
|
||||||
Parameters parameters = Parameters::Builder()
|
Parameters parameters = Parameters::Builder()
|
||||||
.Add(HeartbeatInfoParameter(info.Serialize()))
|
.Add(HeartbeatInfoParameter(info.Serialize()))
|
||||||
@ -185,14 +187,14 @@ DurationMs HeartbeatHandler::OnIntervalTimerExpiry() {
|
|||||||
<< log_prefix_
|
<< log_prefix_
|
||||||
<< "Will not send HEARTBEAT when connection not established";
|
<< "Will not send HEARTBEAT when connection not established";
|
||||||
}
|
}
|
||||||
return DurationMs(0);
|
return TimeDelta::Zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
DurationMs HeartbeatHandler::OnTimeoutTimerExpiry() {
|
TimeDelta HeartbeatHandler::OnTimeoutTimerExpiry() {
|
||||||
// Note that the timeout timer is not restarted. It will be started again when
|
// Note that the timeout timer is not restarted. It will be started again when
|
||||||
// the interval timer expires.
|
// the interval timer expires.
|
||||||
RTC_DCHECK(!timeout_timer_->is_running());
|
RTC_DCHECK(!timeout_timer_->is_running());
|
||||||
ctx_->IncrementTxErrorCounter("HEARTBEAT timeout");
|
ctx_->IncrementTxErrorCounter("HEARTBEAT timeout");
|
||||||
return DurationMs(0);
|
return TimeDelta::Zero();
|
||||||
}
|
}
|
||||||
} // namespace dcsctp
|
} // namespace dcsctp
|
||||||
|
|||||||
@ -50,8 +50,8 @@ class HeartbeatHandler {
|
|||||||
void HandleHeartbeatAck(HeartbeatAckChunk chunk);
|
void HandleHeartbeatAck(HeartbeatAckChunk chunk);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DurationMs OnIntervalTimerExpiry();
|
webrtc::TimeDelta OnIntervalTimerExpiry();
|
||||||
DurationMs OnTimeoutTimerExpiry();
|
webrtc::TimeDelta OnTimeoutTimerExpiry();
|
||||||
|
|
||||||
const absl::string_view log_prefix_;
|
const absl::string_view log_prefix_;
|
||||||
Context* ctx_;
|
Context* ctx_;
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
|
#include "api/units/time_delta.h"
|
||||||
#include "net/dcsctp/common/internal_types.h"
|
#include "net/dcsctp/common/internal_types.h"
|
||||||
#include "net/dcsctp/common/str_join.h"
|
#include "net/dcsctp/common/str_join.h"
|
||||||
#include "net/dcsctp/packet/chunk/reconfig_chunk.h"
|
#include "net/dcsctp/packet/chunk/reconfig_chunk.h"
|
||||||
@ -38,6 +39,7 @@
|
|||||||
|
|
||||||
namespace dcsctp {
|
namespace dcsctp {
|
||||||
namespace {
|
namespace {
|
||||||
|
using ::webrtc::TimeDelta;
|
||||||
using ResponseResult = ReconfigurationResponseParameter::Result;
|
using ResponseResult = ReconfigurationResponseParameter::Result;
|
||||||
|
|
||||||
bool DescriptorsAre(const std::vector<ParameterDescriptor>& c,
|
bool DescriptorsAre(const std::vector<ParameterDescriptor>& c,
|
||||||
@ -277,7 +279,7 @@ void StreamResetHandler::HandleResponse(const ParameterDescriptor& descriptor) {
|
|||||||
});
|
});
|
||||||
// Force this request to be sent again, but with new req_seq_nbr.
|
// Force this request to be sent again, but with new req_seq_nbr.
|
||||||
current_request_->PrepareRetransmission();
|
current_request_->PrepareRetransmission();
|
||||||
reconfig_timer_->set_duration(DurationMs(ctx_->current_rto()));
|
reconfig_timer_->set_duration(ctx_->current_rto());
|
||||||
reconfig_timer_->Start();
|
reconfig_timer_->Start();
|
||||||
break;
|
break;
|
||||||
case ResponseResult::kErrorRequestAlreadyInProgress:
|
case ResponseResult::kErrorRequestAlreadyInProgress:
|
||||||
@ -312,7 +314,7 @@ absl::optional<ReConfigChunk> StreamResetHandler::MakeStreamResetRequest() {
|
|||||||
|
|
||||||
current_request_.emplace(retransmission_queue_->last_assigned_tsn(),
|
current_request_.emplace(retransmission_queue_->last_assigned_tsn(),
|
||||||
retransmission_queue_->BeginResetStreams());
|
retransmission_queue_->BeginResetStreams());
|
||||||
reconfig_timer_->set_duration(DurationMs(ctx_->current_rto()));
|
reconfig_timer_->set_duration(ctx_->current_rto());
|
||||||
reconfig_timer_->Start();
|
reconfig_timer_->Start();
|
||||||
return MakeReconfigChunk();
|
return MakeReconfigChunk();
|
||||||
}
|
}
|
||||||
@ -347,13 +349,13 @@ void StreamResetHandler::ResetStreams(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DurationMs StreamResetHandler::OnReconfigTimerExpiry() {
|
TimeDelta StreamResetHandler::OnReconfigTimerExpiry() {
|
||||||
if (current_request_->has_been_sent()) {
|
if (current_request_->has_been_sent()) {
|
||||||
// There is an outstanding request, which timed out while waiting for a
|
// There is an outstanding request, which timed out while waiting for a
|
||||||
// response.
|
// response.
|
||||||
if (!ctx_->IncrementTxErrorCounter("RECONFIG timeout")) {
|
if (!ctx_->IncrementTxErrorCounter("RECONFIG timeout")) {
|
||||||
// Timed out. The connection will close after processing the timers.
|
// Timed out. The connection will close after processing the timers.
|
||||||
return DurationMs(0);
|
return TimeDelta::Zero();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// There is no outstanding request, but there is a prepared one. This means
|
// There is no outstanding request, but there is a prepared one. This means
|
||||||
@ -362,7 +364,7 @@ DurationMs StreamResetHandler::OnReconfigTimerExpiry() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx_->Send(ctx_->PacketBuilder().Add(MakeReconfigChunk()));
|
ctx_->Send(ctx_->PacketBuilder().Add(MakeReconfigChunk()));
|
||||||
return DurationMs(ctx_->current_rto());
|
return ctx_->current_rto();
|
||||||
}
|
}
|
||||||
|
|
||||||
HandoverReadinessStatus StreamResetHandler::GetHandoverReadiness() const {
|
HandoverReadinessStatus StreamResetHandler::GetHandoverReadiness() const {
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/array_view.h"
|
#include "api/array_view.h"
|
||||||
|
#include "api/units/time_delta.h"
|
||||||
#include "net/dcsctp/common/internal_types.h"
|
#include "net/dcsctp/common/internal_types.h"
|
||||||
#include "net/dcsctp/packet/chunk/reconfig_chunk.h"
|
#include "net/dcsctp/packet/chunk/reconfig_chunk.h"
|
||||||
#include "net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.h"
|
#include "net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.h"
|
||||||
@ -80,7 +81,7 @@ class StreamResetHandler {
|
|||||||
reconfig_timer_(timer_manager->CreateTimer(
|
reconfig_timer_(timer_manager->CreateTimer(
|
||||||
"re-config",
|
"re-config",
|
||||||
absl::bind_front(&StreamResetHandler::OnReconfigTimerExpiry, this),
|
absl::bind_front(&StreamResetHandler::OnReconfigTimerExpiry, this),
|
||||||
TimerOptions(DurationMs(0)))),
|
TimerOptions(webrtc::TimeDelta::Zero()))),
|
||||||
next_outgoing_req_seq_nbr_(
|
next_outgoing_req_seq_nbr_(
|
||||||
handover_state
|
handover_state
|
||||||
? ReconfigRequestSN(handover_state->tx.next_reset_req_sn)
|
? ReconfigRequestSN(handover_state->tx.next_reset_req_sn)
|
||||||
@ -211,7 +212,7 @@ class StreamResetHandler {
|
|||||||
void HandleResponse(const ParameterDescriptor& descriptor);
|
void HandleResponse(const ParameterDescriptor& descriptor);
|
||||||
|
|
||||||
// Expiration handler for the Reconfig timer.
|
// Expiration handler for the Reconfig timer.
|
||||||
DurationMs OnReconfigTimerExpiry();
|
webrtc::TimeDelta OnReconfigTimerExpiry();
|
||||||
|
|
||||||
const absl::string_view log_prefix_;
|
const absl::string_view log_prefix_;
|
||||||
Context* ctx_;
|
Context* ctx_;
|
||||||
|
|||||||
@ -98,12 +98,12 @@ class StreamResetHandlerTest : public testing::Test {
|
|||||||
}),
|
}),
|
||||||
delayed_ack_timer_(timer_manager_.CreateTimer(
|
delayed_ack_timer_(timer_manager_.CreateTimer(
|
||||||
"test/delayed_ack",
|
"test/delayed_ack",
|
||||||
[]() { return DurationMs(0); },
|
[]() { return TimeDelta::Zero(); },
|
||||||
TimerOptions(DurationMs(0)))),
|
TimerOptions(TimeDelta::Zero()))),
|
||||||
t3_rtx_timer_(timer_manager_.CreateTimer(
|
t3_rtx_timer_(timer_manager_.CreateTimer(
|
||||||
"test/t3_rtx",
|
"test/t3_rtx",
|
||||||
[]() { return DurationMs(0); },
|
[]() { return TimeDelta::Zero(); },
|
||||||
TimerOptions(DurationMs(0)))),
|
TimerOptions(TimeDelta::Zero()))),
|
||||||
data_tracker_(std::make_unique<DataTracker>("log: ",
|
data_tracker_(std::make_unique<DataTracker>("log: ",
|
||||||
delayed_ack_timer_.get(),
|
delayed_ack_timer_.get(),
|
||||||
kPeerInitialTsn)),
|
kPeerInitialTsn)),
|
||||||
@ -205,8 +205,8 @@ class StreamResetHandlerTest : public testing::Test {
|
|||||||
std::make_unique<ReassemblyQueue>("log: ", kPeerInitialTsn, kArwnd);
|
std::make_unique<ReassemblyQueue>("log: ", kPeerInitialTsn, kArwnd);
|
||||||
reasm_->RestoreFromState(state);
|
reasm_->RestoreFromState(state);
|
||||||
retransmission_queue_ = std::make_unique<RetransmissionQueue>(
|
retransmission_queue_ = std::make_unique<RetransmissionQueue>(
|
||||||
"", &callbacks_, kMyInitialTsn, kArwnd, producer_,
|
"", &callbacks_, kMyInitialTsn, kArwnd, producer_, [](TimeDelta rtt) {},
|
||||||
[](TimeDelta rtt) {}, []() {}, *t3_rtx_timer_, DcSctpOptions(),
|
[]() {}, *t3_rtx_timer_, DcSctpOptions(),
|
||||||
/*supports_partial_reliability=*/true,
|
/*supports_partial_reliability=*/true,
|
||||||
/*use_message_interleaving=*/false);
|
/*use_message_interleaving=*/false);
|
||||||
retransmission_queue_->RestoreFromState(state);
|
retransmission_queue_->RestoreFromState(state);
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
|
#include "api/units/time_delta.h"
|
||||||
#include "net/dcsctp/packet/chunk/data_chunk.h"
|
#include "net/dcsctp/packet/chunk/data_chunk.h"
|
||||||
#include "net/dcsctp/packet/chunk/forward_tsn_chunk.h"
|
#include "net/dcsctp/packet/chunk/forward_tsn_chunk.h"
|
||||||
#include "net/dcsctp/packet/chunk/idata_chunk.h"
|
#include "net/dcsctp/packet/chunk/idata_chunk.h"
|
||||||
@ -62,20 +63,20 @@ TransmissionControlBlock::TransmissionControlBlock(
|
|||||||
t3_rtx_(timer_manager_.CreateTimer(
|
t3_rtx_(timer_manager_.CreateTimer(
|
||||||
"t3-rtx",
|
"t3-rtx",
|
||||||
absl::bind_front(&TransmissionControlBlock::OnRtxTimerExpiry, this),
|
absl::bind_front(&TransmissionControlBlock::OnRtxTimerExpiry, this),
|
||||||
TimerOptions(options.rto_initial,
|
TimerOptions(options.rto_initial.ToTimeDelta(),
|
||||||
TimerBackoffAlgorithm::kExponential,
|
TimerBackoffAlgorithm::kExponential,
|
||||||
/*max_restarts=*/absl::nullopt,
|
/*max_restarts=*/absl::nullopt,
|
||||||
options.max_timer_backoff_duration.has_value()
|
options.max_timer_backoff_duration.has_value()
|
||||||
? *options.max_timer_backoff_duration
|
? options.max_timer_backoff_duration->ToTimeDelta()
|
||||||
: DurationMs::InfiniteDuration()))),
|
: TimeDelta::PlusInfinity()))),
|
||||||
delayed_ack_timer_(timer_manager_.CreateTimer(
|
delayed_ack_timer_(timer_manager_.CreateTimer(
|
||||||
"delayed-ack",
|
"delayed-ack",
|
||||||
absl::bind_front(&TransmissionControlBlock::OnDelayedAckTimerExpiry,
|
absl::bind_front(&TransmissionControlBlock::OnDelayedAckTimerExpiry,
|
||||||
this),
|
this),
|
||||||
TimerOptions(options.delayed_ack_max_timeout,
|
TimerOptions(options.delayed_ack_max_timeout.ToTimeDelta(),
|
||||||
TimerBackoffAlgorithm::kExponential,
|
TimerBackoffAlgorithm::kExponential,
|
||||||
/*max_restarts=*/0,
|
/*max_restarts=*/0,
|
||||||
/*max_backoff_duration=*/DurationMs::InfiniteDuration(),
|
/*max_backoff_duration=*/TimeDelta::PlusInfinity(),
|
||||||
webrtc::TaskQueueBase::DelayPrecision::kHigh))),
|
webrtc::TaskQueueBase::DelayPrecision::kHigh))),
|
||||||
my_verification_tag_(my_verification_tag),
|
my_verification_tag_(my_verification_tag),
|
||||||
my_initial_tsn_(my_initial_tsn),
|
my_initial_tsn_(my_initial_tsn),
|
||||||
@ -120,14 +121,14 @@ void TransmissionControlBlock::ObserveRTT(TimeDelta rtt) {
|
|||||||
<< ", srtt=" << webrtc::ToString(rto_.srtt())
|
<< ", srtt=" << webrtc::ToString(rto_.srtt())
|
||||||
<< ", rto=" << webrtc::ToString(rto_.rto()) << " ("
|
<< ", rto=" << webrtc::ToString(rto_.rto()) << " ("
|
||||||
<< webrtc::ToString(prev_rto) << ")";
|
<< webrtc::ToString(prev_rto) << ")";
|
||||||
t3_rtx_->set_duration(DurationMs(rto_.rto()));
|
t3_rtx_->set_duration(rto_.rto());
|
||||||
|
|
||||||
DurationMs delayed_ack_tmo =
|
TimeDelta delayed_ack_tmo = std::min(
|
||||||
std::min(DurationMs(rto_.rto()) * 0.5, options_.delayed_ack_max_timeout);
|
rto_.rto() * 0.5, options_.delayed_ack_max_timeout.ToTimeDelta());
|
||||||
delayed_ack_timer_->set_duration(delayed_ack_tmo);
|
delayed_ack_timer_->set_duration(delayed_ack_tmo);
|
||||||
}
|
}
|
||||||
|
|
||||||
DurationMs TransmissionControlBlock::OnRtxTimerExpiry() {
|
TimeDelta TransmissionControlBlock::OnRtxTimerExpiry() {
|
||||||
TimeMs now = callbacks_.TimeMillis();
|
TimeMs now = callbacks_.TimeMillis();
|
||||||
RTC_DLOG(LS_INFO) << log_prefix_ << "Timer " << t3_rtx_->name()
|
RTC_DLOG(LS_INFO) << log_prefix_ << "Timer " << t3_rtx_->name()
|
||||||
<< " has expired";
|
<< " has expired";
|
||||||
@ -141,13 +142,13 @@ DurationMs TransmissionControlBlock::OnRtxTimerExpiry() {
|
|||||||
SendBufferedPackets(now);
|
SendBufferedPackets(now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DurationMs(0);
|
return TimeDelta::Zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
DurationMs TransmissionControlBlock::OnDelayedAckTimerExpiry() {
|
TimeDelta TransmissionControlBlock::OnDelayedAckTimerExpiry() {
|
||||||
data_tracker_.HandleDelayedAckTimerExpiry();
|
data_tracker_.HandleDelayedAckTimerExpiry();
|
||||||
MaybeSendSack();
|
MaybeSendSack();
|
||||||
return DurationMs(0);
|
return TimeDelta::Zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransmissionControlBlock::MaybeSendSack() {
|
void TransmissionControlBlock::MaybeSendSack() {
|
||||||
|
|||||||
@ -149,9 +149,9 @@ class TransmissionControlBlock : public Context {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Will be called when the retransmission timer (t3-rtx) expires.
|
// Will be called when the retransmission timer (t3-rtx) expires.
|
||||||
DurationMs OnRtxTimerExpiry();
|
webrtc::TimeDelta OnRtxTimerExpiry();
|
||||||
// Will be called when the delayed ack timer expires.
|
// Will be called when the delayed ack timer expires.
|
||||||
DurationMs OnDelayedAckTimerExpiry();
|
webrtc::TimeDelta OnDelayedAckTimerExpiry();
|
||||||
|
|
||||||
const absl::string_view log_prefix_;
|
const absl::string_view log_prefix_;
|
||||||
const DcSctpOptions options_;
|
const DcSctpOptions options_;
|
||||||
|
|||||||
@ -12,6 +12,7 @@ rtc_library("timer") {
|
|||||||
deps = [
|
deps = [
|
||||||
"../../../api:array_view",
|
"../../../api:array_view",
|
||||||
"../../../api/task_queue:task_queue",
|
"../../../api/task_queue:task_queue",
|
||||||
|
"../../../api/units:time_delta",
|
||||||
"../../../rtc_base:checks",
|
"../../../rtc_base:checks",
|
||||||
"../../../rtc_base:strong_alias",
|
"../../../rtc_base:strong_alias",
|
||||||
"../../../rtc_base/containers:flat_map",
|
"../../../rtc_base/containers:flat_map",
|
||||||
@ -57,6 +58,7 @@ if (rtc_include_tests) {
|
|||||||
":task_queue_timeout",
|
":task_queue_timeout",
|
||||||
":timer",
|
":timer",
|
||||||
"../../../api:array_view",
|
"../../../api:array_view",
|
||||||
|
"../../../api/units:time_delta",
|
||||||
"../../../api/task_queue:task_queue",
|
"../../../api/task_queue:task_queue",
|
||||||
"../../../api/task_queue/test:mock_task_queue_base",
|
"../../../api/task_queue/test:mock_task_queue_base",
|
||||||
"../../../rtc_base:checks",
|
"../../../rtc_base:checks",
|
||||||
|
|||||||
@ -22,21 +22,23 @@
|
|||||||
|
|
||||||
namespace dcsctp {
|
namespace dcsctp {
|
||||||
namespace {
|
namespace {
|
||||||
|
using ::webrtc::TimeDelta;
|
||||||
|
|
||||||
TimeoutID MakeTimeoutId(TimerID timer_id, TimerGeneration generation) {
|
TimeoutID MakeTimeoutId(TimerID timer_id, TimerGeneration generation) {
|
||||||
return TimeoutID(static_cast<uint64_t>(*timer_id) << 32 | *generation);
|
return TimeoutID(static_cast<uint64_t>(*timer_id) << 32 | *generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
DurationMs GetBackoffDuration(const TimerOptions& options,
|
TimeDelta GetBackoffDuration(const TimerOptions& options,
|
||||||
DurationMs base_duration,
|
TimeDelta base_duration,
|
||||||
int expiration_count) {
|
int expiration_count) {
|
||||||
switch (options.backoff_algorithm) {
|
switch (options.backoff_algorithm) {
|
||||||
case TimerBackoffAlgorithm::kFixed:
|
case TimerBackoffAlgorithm::kFixed:
|
||||||
return base_duration;
|
return base_duration;
|
||||||
case TimerBackoffAlgorithm::kExponential: {
|
case TimerBackoffAlgorithm::kExponential: {
|
||||||
DurationMs duration = base_duration;
|
TimeDelta duration = base_duration;
|
||||||
|
|
||||||
while (expiration_count > 0 && duration < Timer::kMaxTimerDuration) {
|
while (expiration_count > 0 && duration < Timer::kMaxTimerDuration) {
|
||||||
duration *= 2;
|
duration = duration * 2;
|
||||||
--expiration_count;
|
--expiration_count;
|
||||||
|
|
||||||
if (duration > options.max_backoff_duration) {
|
if (duration > options.max_backoff_duration) {
|
||||||
@ -44,13 +46,13 @@ DurationMs GetBackoffDuration(const TimerOptions& options,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return DurationMs(std::min(duration, Timer::kMaxTimerDuration));
|
return TimeDelta(std::min(duration, Timer::kMaxTimerDuration));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
constexpr DurationMs Timer::kMaxTimerDuration;
|
constexpr TimeDelta Timer::kMaxTimerDuration;
|
||||||
|
|
||||||
Timer::Timer(TimerID id,
|
Timer::Timer(TimerID id,
|
||||||
absl::string_view name,
|
absl::string_view name,
|
||||||
@ -76,12 +78,12 @@ void Timer::Start() {
|
|||||||
if (!is_running()) {
|
if (!is_running()) {
|
||||||
is_running_ = true;
|
is_running_ = true;
|
||||||
generation_ = TimerGeneration(*generation_ + 1);
|
generation_ = TimerGeneration(*generation_ + 1);
|
||||||
timeout_->Start(duration_, MakeTimeoutId(id_, generation_));
|
timeout_->Start(DurationMs(duration_), MakeTimeoutId(id_, generation_));
|
||||||
} else {
|
} else {
|
||||||
// Timer was running - stop and restart it, to make it expire in `duration_`
|
// Timer was running - stop and restart it, to make it expire in `duration_`
|
||||||
// from now.
|
// from now.
|
||||||
generation_ = TimerGeneration(*generation_ + 1);
|
generation_ = TimerGeneration(*generation_ + 1);
|
||||||
timeout_->Restart(duration_, MakeTimeoutId(id_, generation_));
|
timeout_->Restart(DurationMs(duration_), MakeTimeoutId(id_, generation_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,24 +105,24 @@ void Timer::Trigger(TimerGeneration generation) {
|
|||||||
// timer. Note that it might be very quickly restarted again, if the
|
// timer. Note that it might be very quickly restarted again, if the
|
||||||
// `on_expired_` callback returns a new duration.
|
// `on_expired_` callback returns a new duration.
|
||||||
is_running_ = true;
|
is_running_ = true;
|
||||||
DurationMs duration =
|
TimeDelta duration =
|
||||||
GetBackoffDuration(options_, duration_, expiration_count_);
|
GetBackoffDuration(options_, duration_, expiration_count_);
|
||||||
generation_ = TimerGeneration(*generation_ + 1);
|
generation_ = TimerGeneration(*generation_ + 1);
|
||||||
timeout_->Start(duration, MakeTimeoutId(id_, generation_));
|
timeout_->Start(DurationMs(duration), MakeTimeoutId(id_, generation_));
|
||||||
}
|
}
|
||||||
|
|
||||||
DurationMs new_duration = on_expired_();
|
TimeDelta new_duration = on_expired_();
|
||||||
RTC_DCHECK(new_duration != DurationMs::InfiniteDuration());
|
RTC_DCHECK(new_duration != TimeDelta::PlusInfinity());
|
||||||
if (new_duration > DurationMs(0) && new_duration != duration_) {
|
if (new_duration > TimeDelta::Zero() && new_duration != duration_) {
|
||||||
duration_ = new_duration;
|
duration_ = new_duration;
|
||||||
if (is_running_) {
|
if (is_running_) {
|
||||||
// Restart it with new duration.
|
// Restart it with new duration.
|
||||||
timeout_->Stop();
|
timeout_->Stop();
|
||||||
|
|
||||||
DurationMs duration =
|
TimeDelta duration =
|
||||||
GetBackoffDuration(options_, duration_, expiration_count_);
|
GetBackoffDuration(options_, duration_, expiration_count_);
|
||||||
generation_ = TimerGeneration(*generation_ + 1);
|
generation_ = TimerGeneration(*generation_ + 1);
|
||||||
timeout_->Start(duration, MakeTimeoutId(id_, generation_));
|
timeout_->Start(DurationMs(duration), MakeTimeoutId(id_, generation_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/task_queue/task_queue_base.h"
|
#include "api/task_queue/task_queue_base.h"
|
||||||
|
#include "api/units/time_delta.h"
|
||||||
#include "net/dcsctp/public/timeout.h"
|
#include "net/dcsctp/public/timeout.h"
|
||||||
#include "rtc_base/strong_alias.h"
|
#include "rtc_base/strong_alias.h"
|
||||||
|
|
||||||
@ -40,30 +41,31 @@ enum class TimerBackoffAlgorithm {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct TimerOptions {
|
struct TimerOptions {
|
||||||
explicit TimerOptions(DurationMs duration)
|
explicit TimerOptions(webrtc::TimeDelta duration)
|
||||||
: TimerOptions(duration, TimerBackoffAlgorithm::kExponential) {}
|
: TimerOptions(duration, TimerBackoffAlgorithm::kExponential) {}
|
||||||
TimerOptions(DurationMs duration, TimerBackoffAlgorithm backoff_algorithm)
|
TimerOptions(webrtc::TimeDelta duration,
|
||||||
|
TimerBackoffAlgorithm backoff_algorithm)
|
||||||
: TimerOptions(duration, backoff_algorithm, absl::nullopt) {}
|
: TimerOptions(duration, backoff_algorithm, absl::nullopt) {}
|
||||||
TimerOptions(DurationMs duration,
|
TimerOptions(webrtc::TimeDelta duration,
|
||||||
TimerBackoffAlgorithm backoff_algorithm,
|
TimerBackoffAlgorithm backoff_algorithm,
|
||||||
absl::optional<int> max_restarts)
|
absl::optional<int> max_restarts)
|
||||||
: TimerOptions(duration,
|
: TimerOptions(duration,
|
||||||
backoff_algorithm,
|
backoff_algorithm,
|
||||||
max_restarts,
|
max_restarts,
|
||||||
DurationMs::InfiniteDuration()) {}
|
webrtc::TimeDelta::PlusInfinity()) {}
|
||||||
TimerOptions(DurationMs duration,
|
TimerOptions(webrtc::TimeDelta duration,
|
||||||
TimerBackoffAlgorithm backoff_algorithm,
|
TimerBackoffAlgorithm backoff_algorithm,
|
||||||
absl::optional<int> max_restarts,
|
absl::optional<int> max_restarts,
|
||||||
DurationMs max_backoff_duration)
|
webrtc::TimeDelta max_backoff_duration)
|
||||||
: TimerOptions(duration,
|
: TimerOptions(duration,
|
||||||
backoff_algorithm,
|
backoff_algorithm,
|
||||||
max_restarts,
|
max_restarts,
|
||||||
max_backoff_duration,
|
max_backoff_duration,
|
||||||
webrtc::TaskQueueBase::DelayPrecision::kLow) {}
|
webrtc::TaskQueueBase::DelayPrecision::kLow) {}
|
||||||
TimerOptions(DurationMs duration,
|
TimerOptions(webrtc::TimeDelta duration,
|
||||||
TimerBackoffAlgorithm backoff_algorithm,
|
TimerBackoffAlgorithm backoff_algorithm,
|
||||||
absl::optional<int> max_restarts,
|
absl::optional<int> max_restarts,
|
||||||
DurationMs max_backoff_duration,
|
webrtc::TimeDelta max_backoff_duration,
|
||||||
webrtc::TaskQueueBase::DelayPrecision precision)
|
webrtc::TaskQueueBase::DelayPrecision precision)
|
||||||
: duration(duration),
|
: duration(duration),
|
||||||
backoff_algorithm(backoff_algorithm),
|
backoff_algorithm(backoff_algorithm),
|
||||||
@ -72,7 +74,7 @@ struct TimerOptions {
|
|||||||
precision(precision) {}
|
precision(precision) {}
|
||||||
|
|
||||||
// The initial timer duration. Can be overridden with `set_duration`.
|
// The initial timer duration. Can be overridden with `set_duration`.
|
||||||
const DurationMs duration;
|
const webrtc::TimeDelta duration;
|
||||||
// If the duration should be increased (using exponential backoff) when it is
|
// If the duration should be increased (using exponential backoff) when it is
|
||||||
// restarted. If not set, the same duration will be used.
|
// restarted. If not set, the same duration will be used.
|
||||||
const TimerBackoffAlgorithm backoff_algorithm;
|
const TimerBackoffAlgorithm backoff_algorithm;
|
||||||
@ -80,7 +82,7 @@ struct TimerOptions {
|
|||||||
// or absl::nullopt if there is no limit.
|
// or absl::nullopt if there is no limit.
|
||||||
const absl::optional<int> max_restarts;
|
const absl::optional<int> max_restarts;
|
||||||
// The maximum timeout value for exponential backoff.
|
// The maximum timeout value for exponential backoff.
|
||||||
const DurationMs max_backoff_duration;
|
const webrtc::TimeDelta max_backoff_duration;
|
||||||
// The precision of the webrtc::TaskQueueBase used for scheduling.
|
// The precision of the webrtc::TaskQueueBase used for scheduling.
|
||||||
const webrtc::TaskQueueBase::DelayPrecision precision;
|
const webrtc::TaskQueueBase::DelayPrecision precision;
|
||||||
};
|
};
|
||||||
@ -100,13 +102,14 @@ struct TimerOptions {
|
|||||||
class Timer {
|
class Timer {
|
||||||
public:
|
public:
|
||||||
// The maximum timer duration - one day.
|
// The maximum timer duration - one day.
|
||||||
static constexpr DurationMs kMaxTimerDuration = DurationMs(24 * 3600 * 1000);
|
static constexpr webrtc::TimeDelta kMaxTimerDuration =
|
||||||
|
webrtc::TimeDelta::Seconds(24 * 3600);
|
||||||
|
|
||||||
// When expired, the timer handler can optionally return a new non-zero
|
// When expired, the timer handler can optionally return a new non-zero
|
||||||
// duration which will be set as `duration` and used as base duration when the
|
// duration which will be set as `duration` and used as base duration when the
|
||||||
// timer is restarted and as input to the backoff algorithm. If zero is
|
// timer is restarted and as input to the backoff algorithm. If zero is
|
||||||
// returned, the current duration is used.
|
// returned, the current duration is used.
|
||||||
using OnExpired = std::function<DurationMs()>;
|
using OnExpired = std::function<webrtc::TimeDelta()>;
|
||||||
|
|
||||||
// TimerManager will have pointers to these instances, so they must not move.
|
// TimerManager will have pointers to these instances, so they must not move.
|
||||||
Timer(const Timer&) = delete;
|
Timer(const Timer&) = delete;
|
||||||
@ -124,13 +127,13 @@ class Timer {
|
|||||||
|
|
||||||
// Sets the base duration. The actual timer duration may be larger depending
|
// Sets the base duration. The actual timer duration may be larger depending
|
||||||
// on the backoff algorithm.
|
// on the backoff algorithm.
|
||||||
void set_duration(DurationMs duration) {
|
void set_duration(webrtc::TimeDelta duration) {
|
||||||
duration_ = std::min(duration, kMaxTimerDuration);
|
duration_ = std::min(duration, kMaxTimerDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieves the base duration. The actual timer duration may be larger
|
// Retrieves the base duration. The actual timer duration may be larger
|
||||||
// depending on the backoff algorithm.
|
// depending on the backoff algorithm.
|
||||||
DurationMs duration() const { return duration_; }
|
webrtc::TimeDelta duration() const { return duration_; }
|
||||||
|
|
||||||
// Returns the number of times the timer has expired.
|
// Returns the number of times the timer has expired.
|
||||||
int expiration_count() const { return expiration_count_; }
|
int expiration_count() const { return expiration_count_; }
|
||||||
@ -168,7 +171,7 @@ class Timer {
|
|||||||
const UnregisterHandler unregister_handler_;
|
const UnregisterHandler unregister_handler_;
|
||||||
const std::unique_ptr<Timeout> timeout_;
|
const std::unique_ptr<Timeout> timeout_;
|
||||||
|
|
||||||
DurationMs duration_;
|
webrtc::TimeDelta duration_;
|
||||||
|
|
||||||
// Increased on each start, and is matched on Trigger, to avoid races. And by
|
// Increased on each start, and is matched on Trigger, to avoid races. And by
|
||||||
// race, meaning that a timeout - which may be evaluated/expired on a
|
// race, meaning that a timeout - which may be evaluated/expired on a
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "api/task_queue/task_queue_base.h"
|
#include "api/task_queue/task_queue_base.h"
|
||||||
|
#include "api/units/time_delta.h"
|
||||||
#include "net/dcsctp/public/timeout.h"
|
#include "net/dcsctp/public/timeout.h"
|
||||||
#include "net/dcsctp/timer/fake_timeout.h"
|
#include "net/dcsctp/timer/fake_timeout.h"
|
||||||
#include "rtc_base/gunit.h"
|
#include "rtc_base/gunit.h"
|
||||||
@ -21,6 +22,7 @@
|
|||||||
namespace dcsctp {
|
namespace dcsctp {
|
||||||
namespace {
|
namespace {
|
||||||
using ::testing::Return;
|
using ::testing::Return;
|
||||||
|
using ::webrtc::TimeDelta;
|
||||||
|
|
||||||
class TimerTest : public testing::Test {
|
class TimerTest : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
@ -29,11 +31,11 @@ class TimerTest : public testing::Test {
|
|||||||
manager_([this](webrtc::TaskQueueBase::DelayPrecision precision) {
|
manager_([this](webrtc::TaskQueueBase::DelayPrecision precision) {
|
||||||
return timeout_manager_.CreateTimeout(precision);
|
return timeout_manager_.CreateTimeout(precision);
|
||||||
}) {
|
}) {
|
||||||
ON_CALL(on_expired_, Call).WillByDefault(Return(DurationMs(0)));
|
ON_CALL(on_expired_, Call).WillByDefault(Return(TimeDelta::Zero()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvanceTimeAndRunTimers(DurationMs duration) {
|
void AdvanceTimeAndRunTimers(TimeDelta duration) {
|
||||||
now_ = now_ + duration;
|
now_ = now_ + DurationMs(duration);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
absl::optional<TimeoutID> timeout_id =
|
absl::optional<TimeoutID> timeout_id =
|
||||||
@ -48,13 +50,13 @@ class TimerTest : public testing::Test {
|
|||||||
TimeMs now_ = TimeMs(0);
|
TimeMs now_ = TimeMs(0);
|
||||||
FakeTimeoutManager timeout_manager_;
|
FakeTimeoutManager timeout_manager_;
|
||||||
TimerManager manager_;
|
TimerManager manager_;
|
||||||
testing::MockFunction<DurationMs()> on_expired_;
|
testing::MockFunction<TimeDelta()> on_expired_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(TimerTest, TimerIsInitiallyStopped) {
|
TEST_F(TimerTest, TimerIsInitiallyStopped) {
|
||||||
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
||||||
"t1", on_expired_.AsStdFunction(),
|
"t1", on_expired_.AsStdFunction(),
|
||||||
TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kFixed));
|
TimerOptions(TimeDelta::Seconds(5), TimerBackoffAlgorithm::kFixed));
|
||||||
|
|
||||||
EXPECT_FALSE(t1->is_running());
|
EXPECT_FALSE(t1->is_running());
|
||||||
}
|
}
|
||||||
@ -62,50 +64,50 @@ TEST_F(TimerTest, TimerIsInitiallyStopped) {
|
|||||||
TEST_F(TimerTest, TimerExpiresAtGivenTime) {
|
TEST_F(TimerTest, TimerExpiresAtGivenTime) {
|
||||||
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
||||||
"t1", on_expired_.AsStdFunction(),
|
"t1", on_expired_.AsStdFunction(),
|
||||||
TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kFixed));
|
TimerOptions(TimeDelta::Seconds(5), TimerBackoffAlgorithm::kFixed));
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
t1->Start();
|
t1->Start();
|
||||||
EXPECT_TRUE(t1->is_running());
|
EXPECT_TRUE(t1->is_running());
|
||||||
|
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(4));
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, TimerReschedulesAfterExpiredWithFixedBackoff) {
|
TEST_F(TimerTest, TimerReschedulesAfterExpiredWithFixedBackoff) {
|
||||||
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
||||||
"t1", on_expired_.AsStdFunction(),
|
"t1", on_expired_.AsStdFunction(),
|
||||||
TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kFixed));
|
TimerOptions(TimeDelta::Seconds(5), TimerBackoffAlgorithm::kFixed));
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
t1->Start();
|
t1->Start();
|
||||||
EXPECT_EQ(t1->expiration_count(), 0);
|
EXPECT_EQ(t1->expiration_count(), 0);
|
||||||
|
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(4));
|
||||||
|
|
||||||
// Fire first time
|
// Fire first time
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
EXPECT_TRUE(t1->is_running());
|
EXPECT_TRUE(t1->is_running());
|
||||||
EXPECT_EQ(t1->expiration_count(), 1);
|
EXPECT_EQ(t1->expiration_count(), 1);
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(4));
|
||||||
|
|
||||||
// Second time
|
// Second time
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
EXPECT_TRUE(t1->is_running());
|
EXPECT_TRUE(t1->is_running());
|
||||||
EXPECT_EQ(t1->expiration_count(), 2);
|
EXPECT_EQ(t1->expiration_count(), 2);
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(4));
|
||||||
|
|
||||||
// Third time
|
// Third time
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
EXPECT_TRUE(t1->is_running());
|
EXPECT_TRUE(t1->is_running());
|
||||||
EXPECT_EQ(t1->expiration_count(), 3);
|
EXPECT_EQ(t1->expiration_count(), 3);
|
||||||
}
|
}
|
||||||
@ -113,151 +115,151 @@ TEST_F(TimerTest, TimerReschedulesAfterExpiredWithFixedBackoff) {
|
|||||||
TEST_F(TimerTest, TimerWithNoRestarts) {
|
TEST_F(TimerTest, TimerWithNoRestarts) {
|
||||||
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
||||||
"t1", on_expired_.AsStdFunction(),
|
"t1", on_expired_.AsStdFunction(),
|
||||||
TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kFixed,
|
TimerOptions(TimeDelta::Seconds(5), TimerBackoffAlgorithm::kFixed,
|
||||||
/*max_restart=*/0));
|
/*max_restart=*/0));
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
t1->Start();
|
t1->Start();
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(4));
|
||||||
|
|
||||||
// Fire first time
|
// Fire first time
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
|
|
||||||
EXPECT_FALSE(t1->is_running());
|
EXPECT_FALSE(t1->is_running());
|
||||||
|
|
||||||
// Second time - shouldn't fire
|
// Second time - shouldn't fire
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(5000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(5));
|
||||||
EXPECT_FALSE(t1->is_running());
|
EXPECT_FALSE(t1->is_running());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, TimerWithOneRestart) {
|
TEST_F(TimerTest, TimerWithOneRestart) {
|
||||||
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
||||||
"t1", on_expired_.AsStdFunction(),
|
"t1", on_expired_.AsStdFunction(),
|
||||||
TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kFixed,
|
TimerOptions(TimeDelta::Seconds(5), TimerBackoffAlgorithm::kFixed,
|
||||||
/*max_restart=*/1));
|
/*max_restart=*/1));
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
t1->Start();
|
t1->Start();
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(4));
|
||||||
|
|
||||||
// Fire first time
|
// Fire first time
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
EXPECT_TRUE(t1->is_running());
|
EXPECT_TRUE(t1->is_running());
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(4));
|
||||||
|
|
||||||
// Second time - max restart limit reached.
|
// Second time - max restart limit reached.
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
EXPECT_FALSE(t1->is_running());
|
EXPECT_FALSE(t1->is_running());
|
||||||
|
|
||||||
// Third time - should not fire.
|
// Third time - should not fire.
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(5000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(5));
|
||||||
EXPECT_FALSE(t1->is_running());
|
EXPECT_FALSE(t1->is_running());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, TimerWithTwoRestart) {
|
TEST_F(TimerTest, TimerWithTwoRestart) {
|
||||||
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
||||||
"t1", on_expired_.AsStdFunction(),
|
"t1", on_expired_.AsStdFunction(),
|
||||||
TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kFixed,
|
TimerOptions(TimeDelta::Seconds(5), TimerBackoffAlgorithm::kFixed,
|
||||||
/*max_restart=*/2));
|
/*max_restart=*/2));
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
t1->Start();
|
t1->Start();
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(4));
|
||||||
|
|
||||||
// Fire first time
|
// Fire first time
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
EXPECT_TRUE(t1->is_running());
|
EXPECT_TRUE(t1->is_running());
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(4));
|
||||||
|
|
||||||
// Second time
|
// Second time
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
EXPECT_TRUE(t1->is_running());
|
EXPECT_TRUE(t1->is_running());
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(4));
|
||||||
|
|
||||||
// Third time
|
// Third time
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
EXPECT_FALSE(t1->is_running());
|
EXPECT_FALSE(t1->is_running());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, TimerWithExponentialBackoff) {
|
TEST_F(TimerTest, TimerWithExponentialBackoff) {
|
||||||
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
||||||
"t1", on_expired_.AsStdFunction(),
|
"t1", on_expired_.AsStdFunction(),
|
||||||
TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kExponential));
|
TimerOptions(TimeDelta::Seconds(5), TimerBackoffAlgorithm::kExponential));
|
||||||
|
|
||||||
t1->Start();
|
t1->Start();
|
||||||
|
|
||||||
// Fire first time at 5 seconds
|
// Fire first time at 5 seconds
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(5000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(5));
|
||||||
|
|
||||||
// Second time at 5*2^1 = 10 seconds later.
|
// Second time at 5*2^1 = 10 seconds later.
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(9000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(9));
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
|
|
||||||
// Third time at 5*2^2 = 20 seconds later.
|
// Third time at 5*2^2 = 20 seconds later.
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(19000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(19));
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
|
|
||||||
// Fourth time at 5*2^3 = 40 seconds later.
|
// Fourth time at 5*2^3 = 40 seconds later.
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(39000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(39));
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, StartTimerWillStopAndStart) {
|
TEST_F(TimerTest, StartTimerWillStopAndStart) {
|
||||||
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
||||||
"t1", on_expired_.AsStdFunction(),
|
"t1", on_expired_.AsStdFunction(),
|
||||||
TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kExponential));
|
TimerOptions(TimeDelta::Seconds(5), TimerBackoffAlgorithm::kExponential));
|
||||||
|
|
||||||
t1->Start();
|
t1->Start();
|
||||||
|
|
||||||
AdvanceTimeAndRunTimers(DurationMs(3000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(3));
|
||||||
|
|
||||||
t1->Start();
|
t1->Start();
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(2000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(2));
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(3000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, ExpirationCounterWillResetIfStopped) {
|
TEST_F(TimerTest, ExpirationCounterWillResetIfStopped) {
|
||||||
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
||||||
"t1", on_expired_.AsStdFunction(),
|
"t1", on_expired_.AsStdFunction(),
|
||||||
TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kExponential));
|
TimerOptions(TimeDelta::Seconds(5), TimerBackoffAlgorithm::kExponential));
|
||||||
|
|
||||||
t1->Start();
|
t1->Start();
|
||||||
|
|
||||||
// Fire first time at 5 seconds
|
// Fire first time at 5 seconds
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(5000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(5));
|
||||||
EXPECT_EQ(t1->expiration_count(), 1);
|
EXPECT_EQ(t1->expiration_count(), 1);
|
||||||
|
|
||||||
// Second time at 5*2^1 = 10 seconds later.
|
// Second time at 5*2^1 = 10 seconds later.
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(9000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(9));
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
EXPECT_EQ(t1->expiration_count(), 2);
|
EXPECT_EQ(t1->expiration_count(), 2);
|
||||||
|
|
||||||
t1->Start();
|
t1->Start();
|
||||||
@ -265,79 +267,79 @@ TEST_F(TimerTest, ExpirationCounterWillResetIfStopped) {
|
|||||||
|
|
||||||
// Third time at 5*2^0 = 5 seconds later.
|
// Third time at 5*2^0 = 5 seconds later.
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(4));
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
EXPECT_EQ(t1->expiration_count(), 1);
|
EXPECT_EQ(t1->expiration_count(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, StopTimerWillMakeItNotExpire) {
|
TEST_F(TimerTest, StopTimerWillMakeItNotExpire) {
|
||||||
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
||||||
"t1", on_expired_.AsStdFunction(),
|
"t1", on_expired_.AsStdFunction(),
|
||||||
TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kExponential));
|
TimerOptions(TimeDelta::Seconds(5), TimerBackoffAlgorithm::kExponential));
|
||||||
|
|
||||||
t1->Start();
|
t1->Start();
|
||||||
EXPECT_TRUE(t1->is_running());
|
EXPECT_TRUE(t1->is_running());
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(4));
|
||||||
t1->Stop();
|
t1->Stop();
|
||||||
EXPECT_FALSE(t1->is_running());
|
EXPECT_FALSE(t1->is_running());
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, ReturningNewDurationWhenExpired) {
|
TEST_F(TimerTest, ReturningNewDurationWhenExpired) {
|
||||||
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
||||||
"t1", on_expired_.AsStdFunction(),
|
"t1", on_expired_.AsStdFunction(),
|
||||||
TimerOptions(DurationMs(5000), TimerBackoffAlgorithm::kFixed));
|
TimerOptions(TimeDelta::Seconds(5), TimerBackoffAlgorithm::kFixed));
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
t1->Start();
|
t1->Start();
|
||||||
EXPECT_EQ(t1->duration(), DurationMs(5000));
|
EXPECT_EQ(t1->duration(), TimeDelta::Seconds(5));
|
||||||
|
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(4));
|
||||||
|
|
||||||
// Fire first time
|
// Fire first time
|
||||||
EXPECT_CALL(on_expired_, Call).WillOnce(Return(DurationMs(2000)));
|
EXPECT_CALL(on_expired_, Call).WillOnce(Return(TimeDelta::Seconds(2)));
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
EXPECT_EQ(t1->duration(), DurationMs(2000));
|
EXPECT_EQ(t1->duration(), TimeDelta::Seconds(2));
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
|
|
||||||
// Second time
|
// Second time
|
||||||
EXPECT_CALL(on_expired_, Call).WillOnce(Return(DurationMs(10000)));
|
EXPECT_CALL(on_expired_, Call).WillOnce(Return(TimeDelta::Seconds(10)));
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
EXPECT_EQ(t1->duration(), DurationMs(10000));
|
EXPECT_EQ(t1->duration(), TimeDelta::Seconds(10));
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(9000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(9));
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, TimersHaveMaximumDuration) {
|
TEST_F(TimerTest, TimersHaveMaximumDuration) {
|
||||||
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
||||||
"t1", on_expired_.AsStdFunction(),
|
"t1", on_expired_.AsStdFunction(),
|
||||||
TimerOptions(DurationMs(1000), TimerBackoffAlgorithm::kExponential));
|
TimerOptions(TimeDelta::Seconds(1), TimerBackoffAlgorithm::kExponential));
|
||||||
|
|
||||||
t1->set_duration(DurationMs(2 * *Timer::kMaxTimerDuration));
|
t1->set_duration(2 * Timer::kMaxTimerDuration);
|
||||||
EXPECT_EQ(t1->duration(), Timer::kMaxTimerDuration);
|
EXPECT_EQ(t1->duration(), Timer::kMaxTimerDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, TimersHaveMaximumBackoffDuration) {
|
TEST_F(TimerTest, TimersHaveMaximumBackoffDuration) {
|
||||||
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
||||||
"t1", on_expired_.AsStdFunction(),
|
"t1", on_expired_.AsStdFunction(),
|
||||||
TimerOptions(DurationMs(1000), TimerBackoffAlgorithm::kExponential));
|
TimerOptions(TimeDelta::Seconds(1), TimerBackoffAlgorithm::kExponential));
|
||||||
|
|
||||||
t1->Start();
|
t1->Start();
|
||||||
|
|
||||||
int max_exponent = static_cast<int>(log2(*Timer::kMaxTimerDuration / 1000));
|
int max_exponent = static_cast<int>(log2(Timer::kMaxTimerDuration.seconds()));
|
||||||
for (int i = 0; i < max_exponent; ++i) {
|
for (int i = 0; i < max_exponent; ++i) {
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000 * (1 << i)));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1 * (1 << i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reached the maximum duration.
|
// Reached the maximum duration.
|
||||||
@ -357,73 +359,73 @@ TEST_F(TimerTest, TimersHaveMaximumBackoffDuration) {
|
|||||||
TEST_F(TimerTest, TimerCanBeStartedFromWithinExpirationHandler) {
|
TEST_F(TimerTest, TimerCanBeStartedFromWithinExpirationHandler) {
|
||||||
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
||||||
"t1", on_expired_.AsStdFunction(),
|
"t1", on_expired_.AsStdFunction(),
|
||||||
TimerOptions(DurationMs(1000), TimerBackoffAlgorithm::kFixed));
|
TimerOptions(TimeDelta::Seconds(1), TimerBackoffAlgorithm::kFixed));
|
||||||
|
|
||||||
t1->Start();
|
t1->Start();
|
||||||
|
|
||||||
// Start a timer, but don't return any new duration in callback.
|
// Start a timer, but don't return any new duration in callback.
|
||||||
EXPECT_CALL(on_expired_, Call).WillOnce([&]() {
|
EXPECT_CALL(on_expired_, Call).WillOnce([&]() {
|
||||||
EXPECT_TRUE(t1->is_running());
|
EXPECT_TRUE(t1->is_running());
|
||||||
t1->set_duration(DurationMs(5000));
|
t1->set_duration(TimeDelta::Seconds(5));
|
||||||
t1->Start();
|
t1->Start();
|
||||||
return DurationMs(0);
|
return TimeDelta::Zero();
|
||||||
});
|
});
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4999));
|
AdvanceTimeAndRunTimers(TimeDelta::Millis(4999));
|
||||||
|
|
||||||
// Start a timer, and return any new duration in callback.
|
// Start a timer, and return any new duration in callback.
|
||||||
EXPECT_CALL(on_expired_, Call).WillOnce([&]() {
|
EXPECT_CALL(on_expired_, Call).WillOnce([&]() {
|
||||||
EXPECT_TRUE(t1->is_running());
|
EXPECT_TRUE(t1->is_running());
|
||||||
t1->set_duration(DurationMs(5000));
|
t1->set_duration(TimeDelta::Seconds(5));
|
||||||
t1->Start();
|
t1->Start();
|
||||||
return DurationMs(8000);
|
return TimeDelta::Seconds(8);
|
||||||
});
|
});
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1));
|
AdvanceTimeAndRunTimers(TimeDelta::Millis(1));
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(7999));
|
AdvanceTimeAndRunTimers(TimeDelta::Millis(7999));
|
||||||
|
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1));
|
AdvanceTimeAndRunTimers(TimeDelta::Millis(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TimerTest, DurationStaysWithinMaxTimerBackOffDuration) {
|
TEST_F(TimerTest, DurationStaysWithinMaxTimerBackOffDuration) {
|
||||||
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
std::unique_ptr<Timer> t1 = manager_.CreateTimer(
|
||||||
"t1", on_expired_.AsStdFunction(),
|
"t1", on_expired_.AsStdFunction(),
|
||||||
TimerOptions(DurationMs(1000), TimerBackoffAlgorithm::kExponential,
|
TimerOptions(TimeDelta::Seconds(1), TimerBackoffAlgorithm::kExponential,
|
||||||
/*max_restarts=*/absl::nullopt, DurationMs(5000)));
|
/*max_restarts=*/absl::nullopt, TimeDelta::Seconds(5)));
|
||||||
|
|
||||||
t1->Start();
|
t1->Start();
|
||||||
|
|
||||||
// Initial timeout, 1000 ms
|
// Initial timeout, 1000 ms
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1000));
|
AdvanceTimeAndRunTimers(TimeDelta::Seconds(1));
|
||||||
|
|
||||||
// Exponential backoff -> 2000 ms
|
// Exponential backoff -> 2000 ms
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1999));
|
AdvanceTimeAndRunTimers(TimeDelta::Millis(1999));
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1));
|
AdvanceTimeAndRunTimers(TimeDelta::Millis(1));
|
||||||
|
|
||||||
// Exponential backoff -> 4000 ms
|
// Exponential backoff -> 4000 ms
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(3999));
|
AdvanceTimeAndRunTimers(TimeDelta::Millis(3999));
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1));
|
AdvanceTimeAndRunTimers(TimeDelta::Millis(1));
|
||||||
|
|
||||||
// Limited backoff -> 5000ms
|
// Limited backoff -> 5000ms
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4999));
|
AdvanceTimeAndRunTimers(TimeDelta::Millis(4999));
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1));
|
AdvanceTimeAndRunTimers(TimeDelta::Millis(1));
|
||||||
|
|
||||||
// ... where it plateaus
|
// ... where it plateaus
|
||||||
EXPECT_CALL(on_expired_, Call).Times(0);
|
EXPECT_CALL(on_expired_, Call).Times(0);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(4999));
|
AdvanceTimeAndRunTimers(TimeDelta::Millis(4999));
|
||||||
EXPECT_CALL(on_expired_, Call).Times(1);
|
EXPECT_CALL(on_expired_, Call).Times(1);
|
||||||
AdvanceTimeAndRunTimers(DurationMs(1));
|
AdvanceTimeAndRunTimers(TimeDelta::Millis(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TimerManagerTest, TimerManagerPassesPrecisionToCreateTimeoutMethod) {
|
TEST(TimerManagerTest, TimerManagerPassesPrecisionToCreateTimeoutMethod) {
|
||||||
@ -435,22 +437,22 @@ TEST(TimerManagerTest, TimerManagerPassesPrecisionToCreateTimeoutMethod) {
|
|||||||
});
|
});
|
||||||
// Default TimerOptions.
|
// Default TimerOptions.
|
||||||
manager.CreateTimer(
|
manager.CreateTimer(
|
||||||
"test_timer", []() { return DurationMs(0); },
|
"test_timer", []() { return TimeDelta::Zero(); },
|
||||||
TimerOptions(DurationMs(123)));
|
TimerOptions(TimeDelta::Millis(123)));
|
||||||
EXPECT_EQ(create_timer_precison, webrtc::TaskQueueBase::DelayPrecision::kLow);
|
EXPECT_EQ(create_timer_precison, webrtc::TaskQueueBase::DelayPrecision::kLow);
|
||||||
// High precision TimerOptions.
|
// High precision TimerOptions.
|
||||||
manager.CreateTimer(
|
manager.CreateTimer(
|
||||||
"test_timer", []() { return DurationMs(0); },
|
"test_timer", []() { return TimeDelta::Zero(); },
|
||||||
TimerOptions(DurationMs(123), TimerBackoffAlgorithm::kExponential,
|
TimerOptions(TimeDelta::Millis(123), TimerBackoffAlgorithm::kExponential,
|
||||||
absl::nullopt, DurationMs::InfiniteDuration(),
|
absl::nullopt, TimeDelta::PlusInfinity(),
|
||||||
webrtc::TaskQueueBase::DelayPrecision::kHigh));
|
webrtc::TaskQueueBase::DelayPrecision::kHigh));
|
||||||
EXPECT_EQ(create_timer_precison,
|
EXPECT_EQ(create_timer_precison,
|
||||||
webrtc::TaskQueueBase::DelayPrecision::kHigh);
|
webrtc::TaskQueueBase::DelayPrecision::kHigh);
|
||||||
// Low precision TimerOptions.
|
// Low precision TimerOptions.
|
||||||
manager.CreateTimer(
|
manager.CreateTimer(
|
||||||
"test_timer", []() { return DurationMs(0); },
|
"test_timer", []() { return TimeDelta::Zero(); },
|
||||||
TimerOptions(DurationMs(123), TimerBackoffAlgorithm::kExponential,
|
TimerOptions(TimeDelta::Millis(123), TimerBackoffAlgorithm::kExponential,
|
||||||
absl::nullopt, DurationMs::InfiniteDuration(),
|
absl::nullopt, TimeDelta::PlusInfinity(),
|
||||||
webrtc::TaskQueueBase::DelayPrecision::kLow));
|
webrtc::TaskQueueBase::DelayPrecision::kLow));
|
||||||
EXPECT_EQ(create_timer_precison, webrtc::TaskQueueBase::DelayPrecision::kLow);
|
EXPECT_EQ(create_timer_precison, webrtc::TaskQueueBase::DelayPrecision::kLow);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,8 +75,8 @@ class RetransmissionQueueTest : public testing::Test {
|
|||||||
}),
|
}),
|
||||||
timer_(timer_manager_.CreateTimer(
|
timer_(timer_manager_.CreateTimer(
|
||||||
"test/t3_rtx",
|
"test/t3_rtx",
|
||||||
[]() { return DurationMs(0); },
|
[]() { return TimeDelta::Zero(); },
|
||||||
TimerOptions(options_.rto_initial))) {}
|
TimerOptions(options_.rto_initial.ToTimeDelta()))) {}
|
||||||
|
|
||||||
std::function<SendQueue::DataToSend(TimeMs, size_t)> CreateChunk(
|
std::function<SendQueue::DataToSend(TimeMs, size_t)> CreateChunk(
|
||||||
OutgoingMessageId message_id) {
|
OutgoingMessageId message_id) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user