1 /*
2  *  Copyright (c) 2013 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 #ifndef TEST_RUN_LOOP_H_
11 #define TEST_RUN_LOOP_H_
12 
13 #include "rtc_base/task_utils/to_queued_task.h"
14 #include "rtc_base/thread.h"
15 
16 namespace webrtc {
17 namespace test {
18 
19 // This utility class allows you to run a TaskQueue supported interface on the
20 // main test thread, call Run() while doing things asynchonously and break
21 // the loop (from the same thread) from a callback by calling Quit().
22 class RunLoop {
23  public:
24   RunLoop();
25   ~RunLoop();
26 
27   TaskQueueBase* task_queue();
28 
29   void Run();
30   void Quit();
31 
32   void Flush();
33 
34   // Convenience methods since TaskQueueBase doesn't support this sort of magic.
35   template <typename Closure>
PostTask(Closure && task)36   void PostTask(Closure&& task) {
37     task_queue()->PostTask(ToQueuedTask(std::forward<Closure>(task)));
38   }
39 
40   template <typename Closure>
PostDelayedTask(Closure && task,uint32_t milliseconds)41   void PostDelayedTask(Closure&& task, uint32_t milliseconds) {
42     task_queue()->PostDelayedTask(ToQueuedTask(std::forward<Closure>(task)),
43                                   milliseconds);
44   }
45 
46  private:
47   class FakeSocketServer : public rtc::SocketServer {
48    public:
49     FakeSocketServer();
50     ~FakeSocketServer();
51 
52     void FailNextWait();
53 
54    private:
55     bool Wait(int cms, bool process_io) override;
56     void WakeUp() override;
57 
58     rtc::Socket* CreateSocket(int family, int type) override;
59     rtc::AsyncSocket* CreateAsyncSocket(int family, int type) override;
60 
61    private:
62     bool fail_next_wait_ = false;
63   };
64 
65   class WorkerThread : public rtc::Thread {
66    public:
67     explicit WorkerThread(rtc::SocketServer* ss);
68 
69    private:
70     CurrentTaskQueueSetter tq_setter_;
71   };
72 
73   FakeSocketServer socket_server_;
74   WorkerThread worker_thread_{&socket_server_};
75 };
76 
77 }  // namespace test
78 }  // namespace webrtc
79 
80 #endif  // TEST_RUN_LOOP_H_
81