| /* | |
| * 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 |