|  | /* | 
|  | *  Copyright 2018 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 RTC_BASE_TASK_QUEUE_FOR_TEST_H_ | 
|  | #define RTC_BASE_TASK_QUEUE_FOR_TEST_H_ | 
|  |  | 
|  | #include <utility> | 
|  |  | 
|  | #include "absl/cleanup/cleanup.h" | 
|  | #include "absl/strings/string_view.h" | 
|  | #include "api/function_view.h" | 
|  | #include "api/task_queue/task_queue_base.h" | 
|  | #include "api/task_queue/task_queue_factory.h" | 
|  | #include "rtc_base/checks.h" | 
|  | #include "rtc_base/event.h" | 
|  |  | 
|  | namespace webrtc { | 
|  |  | 
|  | inline void SendTask(TaskQueueBase* task_queue, | 
|  | rtc::FunctionView<void()> task) { | 
|  | if (task_queue->IsCurrent()) { | 
|  | task(); | 
|  | return; | 
|  | } | 
|  |  | 
|  | rtc::Event event; | 
|  | absl::Cleanup cleanup = [&event] { event.Set(); }; | 
|  | task_queue->PostTask([task, cleanup = std::move(cleanup)] { task(); }); | 
|  | RTC_CHECK(event.Wait(/*give_up_after=*/rtc::Event::kForever, | 
|  | /*warn_after=*/TimeDelta::Seconds(10))); | 
|  | } | 
|  |  | 
|  | class TaskQueueForTest { | 
|  | public: | 
|  | explicit TaskQueueForTest( | 
|  | std::unique_ptr<TaskQueueBase, TaskQueueDeleter> task_queue); | 
|  | explicit TaskQueueForTest( | 
|  | absl::string_view name = "TestQueue", | 
|  | TaskQueueFactory::Priority priority = TaskQueueFactory::Priority::NORMAL); | 
|  | TaskQueueForTest(const TaskQueueForTest&) = delete; | 
|  | TaskQueueForTest& operator=(const TaskQueueForTest&) = delete; | 
|  | ~TaskQueueForTest(); | 
|  |  | 
|  | bool IsCurrent() const { return impl_->IsCurrent(); } | 
|  |  | 
|  | // Returns non-owning pointer to the task queue implementation. | 
|  | TaskQueueBase* Get() { return impl_.get(); } | 
|  |  | 
|  | void PostTask( | 
|  | absl::AnyInvocable<void() &&> task, | 
|  | const webrtc::Location& location = webrtc::Location::Current()) { | 
|  | impl_->PostTask(std::move(task), location); | 
|  | } | 
|  | void PostDelayedTask( | 
|  | absl::AnyInvocable<void() &&> task, | 
|  | webrtc::TimeDelta delay, | 
|  | const webrtc::Location& location = webrtc::Location::Current()) { | 
|  | impl_->PostDelayedTask(std::move(task), delay, location); | 
|  | } | 
|  | void PostDelayedHighPrecisionTask( | 
|  | absl::AnyInvocable<void() &&> task, | 
|  | webrtc::TimeDelta delay, | 
|  | const webrtc::Location& location = webrtc::Location::Current()) { | 
|  | impl_->PostDelayedHighPrecisionTask(std::move(task), delay, location); | 
|  | } | 
|  |  | 
|  | // A convenience, test-only method that blocks the current thread while | 
|  | // a task executes on the task queue. | 
|  | void SendTask(rtc::FunctionView<void()> task) { | 
|  | ::webrtc::SendTask(Get(), task); | 
|  | } | 
|  |  | 
|  | // Wait for the completion of all tasks posted prior to the | 
|  | // WaitForPreviouslyPostedTasks() call. | 
|  | void WaitForPreviouslyPostedTasks() { | 
|  | RTC_DCHECK(!Get()->IsCurrent()); | 
|  | // Post an empty task on the queue and wait for it to finish, to ensure | 
|  | // that all already posted tasks on the queue get executed. | 
|  | SendTask([]() {}); | 
|  | } | 
|  |  | 
|  | private: | 
|  | std::unique_ptr<TaskQueueBase, TaskQueueDeleter> impl_; | 
|  | }; | 
|  |  | 
|  | }  // namespace webrtc | 
|  |  | 
|  | #endif  // RTC_BASE_TASK_QUEUE_FOR_TEST_H_ |