summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/net/dcsctp/timer/fake_timeout.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/net/dcsctp/timer/fake_timeout.h')
-rw-r--r--third_party/libwebrtc/net/dcsctp/timer/fake_timeout.h122
1 files changed, 122 insertions, 0 deletions
diff --git a/third_party/libwebrtc/net/dcsctp/timer/fake_timeout.h b/third_party/libwebrtc/net/dcsctp/timer/fake_timeout.h
new file mode 100644
index 0000000000..4621b2ce83
--- /dev/null
+++ b/third_party/libwebrtc/net/dcsctp/timer/fake_timeout.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef NET_DCSCTP_TIMER_FAKE_TIMEOUT_H_
+#define NET_DCSCTP_TIMER_FAKE_TIMEOUT_H_
+
+#include <cstdint>
+#include <functional>
+#include <limits>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/task_queue/task_queue_base.h"
+#include "net/dcsctp/public/timeout.h"
+#include "net/dcsctp/public/types.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/containers/flat_set.h"
+
+namespace dcsctp {
+
+// A timeout used in tests.
+class FakeTimeout : public Timeout {
+ public:
+ FakeTimeout(std::function<TimeMs()> get_time,
+ std::function<void(FakeTimeout*)> on_delete)
+ : get_time_(std::move(get_time)), on_delete_(std::move(on_delete)) {}
+
+ ~FakeTimeout() override { on_delete_(this); }
+
+ void Start(DurationMs duration_ms, TimeoutID timeout_id) override {
+ RTC_DCHECK(expiry_ == TimeMs::InfiniteFuture());
+ timeout_id_ = timeout_id;
+ expiry_ = get_time_() + duration_ms;
+ }
+ void Stop() override {
+ RTC_DCHECK(expiry_ != TimeMs::InfiniteFuture());
+ expiry_ = TimeMs::InfiniteFuture();
+ }
+
+ bool EvaluateHasExpired(TimeMs now) {
+ if (now >= expiry_) {
+ expiry_ = TimeMs::InfiniteFuture();
+ return true;
+ }
+ return false;
+ }
+
+ TimeoutID timeout_id() const { return timeout_id_; }
+ TimeMs expiry() const { return expiry_; }
+
+ private:
+ const std::function<TimeMs()> get_time_;
+ const std::function<void(FakeTimeout*)> on_delete_;
+
+ TimeoutID timeout_id_ = TimeoutID(0);
+ TimeMs expiry_ = TimeMs::InfiniteFuture();
+};
+
+class FakeTimeoutManager {
+ public:
+ // The `get_time` function must return the current time, relative to any
+ // epoch.
+ explicit FakeTimeoutManager(std::function<TimeMs()> get_time)
+ : get_time_(std::move(get_time)) {}
+
+ std::unique_ptr<FakeTimeout> CreateTimeout() {
+ auto timer = std::make_unique<FakeTimeout>(
+ get_time_, [this](FakeTimeout* timer) { timers_.erase(timer); });
+ timers_.insert(timer.get());
+ return timer;
+ }
+ std::unique_ptr<FakeTimeout> CreateTimeout(
+ webrtc::TaskQueueBase::DelayPrecision precision) {
+ // FakeTimeout does not support implement |precision|.
+ return CreateTimeout();
+ }
+
+ // NOTE: This can't return a vector, as calling EvaluateHasExpired requires
+ // calling socket->HandleTimeout directly afterwards, as the owning Timer
+ // still believes it's running, and it needs to be updated to set
+ // Timer::is_running_ to false before you operate on the Timer or Timeout
+ // again.
+ absl::optional<TimeoutID> GetNextExpiredTimeout() {
+ TimeMs now = get_time_();
+ std::vector<TimeoutID> expired_timers;
+ for (auto& timer : timers_) {
+ if (timer->EvaluateHasExpired(now)) {
+ return timer->timeout_id();
+ }
+ }
+ return absl::nullopt;
+ }
+
+ DurationMs GetTimeToNextTimeout() const {
+ TimeMs next_expiry = TimeMs::InfiniteFuture();
+ for (const FakeTimeout* timer : timers_) {
+ if (timer->expiry() < next_expiry) {
+ next_expiry = timer->expiry();
+ }
+ }
+ TimeMs now = get_time_();
+ return next_expiry != TimeMs::InfiniteFuture() && next_expiry >= now
+ ? next_expiry - now
+ : DurationMs::InfiniteDuration();
+ }
+
+ private:
+ const std::function<TimeMs()> get_time_;
+ webrtc::flat_set<FakeTimeout*> timers_;
+};
+
+} // namespace dcsctp
+
+#endif // NET_DCSCTP_TIMER_FAKE_TIMEOUT_H_