1 /*
2 * Copyright 2018 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #ifndef RTC_BASE_TASK_QUEUE_FOR_TEST_H_
12 #define RTC_BASE_TASK_QUEUE_FOR_TEST_H_
13
14 #include <utility>
15
16 #include "absl/strings/string_view.h"
17 #include "api/task_queue/task_queue_base.h"
18 #include "rtc_base/checks.h"
19 #include "rtc_base/event.h"
20 #include "rtc_base/location.h"
21 #include "rtc_base/task_queue.h"
22 #include "rtc_base/task_utils/to_queued_task.h"
23 #include "rtc_base/thread_annotations.h"
24
25 namespace webrtc {
26
27 template <typename Closure>
SendTask(rtc::Location loc,TaskQueueBase * task_queue,Closure && task)28 void SendTask(rtc::Location loc, TaskQueueBase* task_queue, Closure&& task) {
29 RTC_CHECK(!task_queue->IsCurrent())
30 << "Called SendTask to a queue from the same queue at " << loc.ToString();
31 rtc::Event event;
32 task_queue->PostTask(
33 ToQueuedTask(std::forward<Closure>(task), [&event] { event.Set(); }));
34 RTC_CHECK(event.Wait(/*give_up_after_ms=*/rtc::Event::kForever,
35 /*warn_after_ms=*/10'000))
36 << "Waited too long at " << loc.ToString();
37 }
38
39 class RTC_LOCKABLE TaskQueueForTest : public rtc::TaskQueue {
40 public:
41 using rtc::TaskQueue::TaskQueue;
42 explicit TaskQueueForTest(absl::string_view name = "TestQueue",
43 Priority priority = Priority::NORMAL);
44 TaskQueueForTest(const TaskQueueForTest&) = delete;
45 TaskQueueForTest& operator=(const TaskQueueForTest&) = delete;
46 ~TaskQueueForTest() = default;
47
48 // A convenience, test-only method that blocks the current thread while
49 // a task executes on the task queue.
50 // This variant is specifically for posting custom QueuedTask derived
51 // implementations that tests do not want to pass ownership of over to the
52 // task queue (i.e. the Run() method always returns |false|.).
53 template <class Closure>
54 void SendTask(Closure* task) {
55 RTC_CHECK(!IsCurrent());
56 rtc::Event event;
57 PostTask(ToQueuedTask(
58 [&task] { RTC_CHECK_EQ(false, static_cast<QueuedTask*>(task)->Run()); },
59 [&event] { event.Set(); }));
60 event.Wait(rtc::Event::kForever);
61 }
62
63 // A convenience, test-only method that blocks the current thread while
64 // a task executes on the task queue.
65 template <class Closure>
66 void SendTask(Closure&& task, rtc::Location loc) {
67 ::webrtc::SendTask(loc, Get(), std::forward<Closure>(task));
68 }
69
70 // Wait for the completion of all tasks posted prior to the
71 // WaitForPreviouslyPostedTasks() call.
72 void WaitForPreviouslyPostedTasks() {
73 // Post an empty task on the queue and wait for it to finish, to ensure
74 // that all already posted tasks on the queue get executed.
75 SendTask([]() {}, RTC_FROM_HERE);
76 }
77 };
78
79 } // namespace webrtc
80
81 #endif // RTC_BASE_TASK_QUEUE_FOR_TEST_H_
82