| /* |
| * Copyright (c) 2022 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 <memory> |
| |
| #include "api/sequence_checker.h" |
| #include "api/task_queue/pending_task_safety_flag.h" |
| #include "api/task_queue/task_queue_factory.h" |
| #include "api/units/time_delta.h" |
| #include "modules/utility/maybe_worker_thread.h" |
| #include "rtc_base/event.h" |
| #include "test/explicit_key_value_config.h" |
| #include "test/gtest.h" |
| #include "test/time_controller/real_time_controller.h" |
| |
| namespace webrtc { |
| |
| namespace { |
| |
| constexpr char kFieldTrialEnabledString[] = |
| "WebRTC-SendPacketsOnWorkerThread/Enabled/"; |
| constexpr char kFieldTrialDisabledString[] = |
| "WebRTC-SendPacketsOnWorkerThread/Disabled/"; |
| |
| TEST(MaybeWorkerThreadTest, RunOrPostRunOnWorkerThreadInExperiment) { |
| test::ExplicitKeyValueConfig field_trial(kFieldTrialEnabledString); |
| RealTimeController controller; |
| MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); |
| |
| SequenceChecker checker; |
| bool run = false; |
| m.RunOrPost([&] { |
| EXPECT_TRUE(checker.IsCurrent()); |
| run = true; |
| }); |
| EXPECT_TRUE(run); |
| } |
| |
| TEST(MaybeWorkerThreadTest, RunOrPostPostsOnTqPerDefault) { |
| test::ExplicitKeyValueConfig field_trial(kFieldTrialDisabledString); |
| RealTimeController controller; |
| MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); |
| |
| SequenceChecker checker; |
| rtc::Event event; |
| m.RunOrPost([&] { |
| EXPECT_FALSE(checker.IsCurrent()); |
| event.Set(); |
| }); |
| EXPECT_TRUE(event.Wait(TimeDelta::Seconds(10))); |
| } |
| |
| TEST(MaybeWorkerThreadTest, RunSynchronousRunOnWorkerThreadInExperiment) { |
| test::ExplicitKeyValueConfig field_trial(kFieldTrialEnabledString); |
| RealTimeController controller; |
| MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); |
| |
| SequenceChecker checker; |
| bool run = false; |
| m.RunSynchronous([&] { |
| EXPECT_TRUE(checker.IsCurrent()); |
| run = true; |
| }); |
| EXPECT_TRUE(run); |
| } |
| |
| TEST(MaybeWorkerThreadTest, RunSynchronousRunOnTqPerDefault) { |
| test::ExplicitKeyValueConfig field_trial(kFieldTrialDisabledString); |
| RealTimeController controller; |
| MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); |
| |
| SequenceChecker checker; |
| bool run = false; |
| m.RunSynchronous([&] { |
| EXPECT_FALSE(checker.IsCurrent()); |
| run = true; |
| }); |
| EXPECT_TRUE(run); |
| } |
| |
| TEST(MaybeWorkerThreadTest, MaybeSafeTaskDoesNotReturnSafeTaskPerDefault) { |
| // We cant really test that the return value from MaybeSafeTask is a SafeTask. |
| // But we can test that the safety flag does not have more references after a |
| // call. |
| test::ExplicitKeyValueConfig field_trial(kFieldTrialDisabledString); |
| RealTimeController controller; |
| MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); |
| |
| rtc::scoped_refptr<PendingTaskSafetyFlag> flag = |
| PendingTaskSafetyFlag::Create(); |
| auto closure = m.MaybeSafeTask(flag, [] {}); |
| EXPECT_EQ(flag->Release(), rtc::RefCountReleaseStatus::kDroppedLastRef); |
| flag.release(); |
| } |
| |
| TEST(MaybeWorkerThreadTest, MaybeSafeTaskDoesNotReturnSafeTaskInExperiment) { |
| // We cant really test that the return value from MaybeSafeTask is a SafeTask. |
| // But we can test that the safety flag does have one more references after a |
| // call. |
| test::ExplicitKeyValueConfig field_trial(kFieldTrialEnabledString); |
| RealTimeController controller; |
| MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); |
| |
| rtc::scoped_refptr<PendingTaskSafetyFlag> flag = |
| PendingTaskSafetyFlag::Create(); |
| auto closure = m.MaybeSafeTask(flag, [] {}); |
| EXPECT_EQ(flag->Release(), rtc::RefCountReleaseStatus::kOtherRefsRemained); |
| flag.release(); |
| } |
| |
| TEST(MaybeWorkerThreadTest, IsCurrentBehavesCorrectPerDefault) { |
| test::ExplicitKeyValueConfig field_trial(kFieldTrialDisabledString); |
| RealTimeController controller; |
| MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); |
| |
| EXPECT_FALSE(m.IsCurrent()); |
| m.RunSynchronous([&] { EXPECT_TRUE(m.IsCurrent()); }); |
| } |
| |
| TEST(MaybeWorkerThreadTest, IsCurrentBehavesCorrectInExperiment) { |
| test::ExplicitKeyValueConfig field_trial(kFieldTrialEnabledString); |
| RealTimeController controller; |
| MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); |
| |
| EXPECT_TRUE(m.IsCurrent()); |
| auto tq = controller.GetTaskQueueFactory()->CreateTaskQueue( |
| "tq", TaskQueueFactory::Priority::NORMAL); |
| rtc::Event event; |
| tq->PostTask([&] { |
| EXPECT_FALSE(m.IsCurrent()); |
| event.Set(); |
| }); |
| ASSERT_TRUE(event.Wait(TimeDelta::Seconds(10))); |
| } |
| |
| TEST(MaybeWorkerThreadTest, IsCurrentCanBeCalledInDestructorPerDefault) { |
| test::ExplicitKeyValueConfig field_trial(kFieldTrialDisabledString); |
| RealTimeController controller; |
| { |
| MaybeWorkerThread m(field_trial, "test_tq", |
| controller.GetTaskQueueFactory()); |
| m.RunOrPost([&] { EXPECT_TRUE(m.IsCurrent()); }); |
| } |
| } |
| |
| TEST(MaybeWorkerThreadTest, IsCurrentCanBeCalledInDestructorInExperiment) { |
| test::ExplicitKeyValueConfig field_trial(kFieldTrialEnabledString); |
| RealTimeController controller; |
| { |
| MaybeWorkerThread m(field_trial, "test_tq", |
| controller.GetTaskQueueFactory()); |
| m.RunOrPost([&] { EXPECT_TRUE(m.IsCurrent()); }); |
| } |
| } |
| |
| } // namespace |
| } // namespace webrtc |