125 lines
3.9 KiB
C++
125 lines
3.9 KiB
C++
/*
|
|
* Copyright (c) 2019 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.
|
|
*/
|
|
|
|
#include "test/pc/e2e/test_activities_executor.h"
|
|
|
|
#include <memory>
|
|
#include <utility>
|
|
|
|
#include "absl/memory/memory.h"
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/location.h"
|
|
#include "rtc_base/logging.h"
|
|
|
|
namespace webrtc {
|
|
namespace webrtc_pc_e2e {
|
|
|
|
void TestActivitiesExecutor::Start(TaskQueueForTest* task_queue) {
|
|
RTC_DCHECK(task_queue);
|
|
task_queue_ = task_queue;
|
|
MutexLock lock(&lock_);
|
|
start_time_ = Now();
|
|
while (!scheduled_activities_.empty()) {
|
|
PostActivity(std::move(scheduled_activities_.front()));
|
|
scheduled_activities_.pop();
|
|
}
|
|
}
|
|
|
|
void TestActivitiesExecutor::Stop() {
|
|
if (task_queue_ == nullptr) {
|
|
// Already stopped or not started.
|
|
return;
|
|
}
|
|
task_queue_->SendTask(
|
|
[this]() {
|
|
MutexLock lock(&lock_);
|
|
for (auto& handle : repeating_task_handles_) {
|
|
handle.Stop();
|
|
}
|
|
},
|
|
RTC_FROM_HERE);
|
|
task_queue_ = nullptr;
|
|
}
|
|
|
|
void TestActivitiesExecutor::ScheduleActivity(
|
|
TimeDelta initial_delay_since_start,
|
|
absl::optional<TimeDelta> interval,
|
|
std::function<void(TimeDelta)> func) {
|
|
RTC_CHECK(initial_delay_since_start.IsFinite() &&
|
|
initial_delay_since_start >= TimeDelta::Zero());
|
|
RTC_CHECK(!interval ||
|
|
(interval->IsFinite() && *interval > TimeDelta::Zero()));
|
|
MutexLock lock(&lock_);
|
|
ScheduledActivity activity(initial_delay_since_start, interval, func);
|
|
if (start_time_.IsInfinite()) {
|
|
scheduled_activities_.push(std::move(activity));
|
|
} else {
|
|
PostActivity(std::move(activity));
|
|
}
|
|
}
|
|
|
|
void TestActivitiesExecutor::PostActivity(ScheduledActivity activity) {
|
|
// Because start_time_ will never change at this point copy it to local
|
|
// variable to capture in in lambda without requirement to hold a lock.
|
|
Timestamp start_time = start_time_;
|
|
|
|
TimeDelta remaining_delay =
|
|
activity.initial_delay_since_start == TimeDelta::Zero()
|
|
? TimeDelta::Zero()
|
|
: activity.initial_delay_since_start - (Now() - start_time);
|
|
if (remaining_delay < TimeDelta::Zero()) {
|
|
RTC_LOG(WARNING) << "Executing late task immediately, late by="
|
|
<< ToString(remaining_delay.Abs());
|
|
remaining_delay = TimeDelta::Zero();
|
|
}
|
|
|
|
if (activity.interval) {
|
|
if (remaining_delay == TimeDelta::Zero()) {
|
|
repeating_task_handles_.push_back(RepeatingTaskHandle::Start(
|
|
task_queue_->Get(), [activity, start_time, this]() {
|
|
activity.func(Now() - start_time);
|
|
return *activity.interval;
|
|
}));
|
|
return;
|
|
}
|
|
repeating_task_handles_.push_back(RepeatingTaskHandle::DelayedStart(
|
|
task_queue_->Get(), remaining_delay, [activity, start_time, this]() {
|
|
activity.func(Now() - start_time);
|
|
return *activity.interval;
|
|
}));
|
|
return;
|
|
}
|
|
|
|
if (remaining_delay == TimeDelta::Zero()) {
|
|
task_queue_->PostTask(
|
|
[activity, start_time, this]() { activity.func(Now() - start_time); });
|
|
return;
|
|
}
|
|
|
|
task_queue_->PostDelayedTask(
|
|
[activity, start_time, this]() { activity.func(Now() - start_time); },
|
|
remaining_delay.ms());
|
|
}
|
|
|
|
Timestamp TestActivitiesExecutor::Now() const {
|
|
return clock_->CurrentTime();
|
|
}
|
|
|
|
TestActivitiesExecutor::ScheduledActivity::ScheduledActivity(
|
|
TimeDelta initial_delay_since_start,
|
|
absl::optional<TimeDelta> interval,
|
|
std::function<void(TimeDelta)> func)
|
|
: initial_delay_since_start(initial_delay_since_start),
|
|
interval(interval),
|
|
func(std::move(func)) {}
|
|
|
|
} // namespace webrtc_pc_e2e
|
|
} // namespace webrtc
|