• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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