xref: /aosp_15_r20/external/webrtc/rtc_base/thread_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <memory>
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker #include "api/field_trials_view.h"
16*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/task_queue_factory.h"
17*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/task_queue_test.h"
18*d9f75844SAndroid Build Coastguard Worker #include "api/units/time_delta.h"
19*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/async_udp_socket.h"
20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
21*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/event.h"
22*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/fake_clock.h"
23*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/gunit.h"
24*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/internal/default_socket_server.h"
25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/null_socket_server.h"
26*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/physical_socket_server.h"
27*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ref_counted_object.h"
28*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/socket_address.h"
29*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/synchronization/mutex.h"
30*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/third_party/sigslot/sigslot.h"
31*d9f75844SAndroid Build Coastguard Worker #include "test/gmock.h"
32*d9f75844SAndroid Build Coastguard Worker #include "test/testsupport/rtc_expect_death.h"
33*d9f75844SAndroid Build Coastguard Worker 
34*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN)
35*d9f75844SAndroid Build Coastguard Worker #include <comdef.h>  // NOLINT
36*d9f75844SAndroid Build Coastguard Worker 
37*d9f75844SAndroid Build Coastguard Worker #endif
38*d9f75844SAndroid Build Coastguard Worker 
39*d9f75844SAndroid Build Coastguard Worker namespace rtc {
40*d9f75844SAndroid Build Coastguard Worker namespace {
41*d9f75844SAndroid Build Coastguard Worker 
42*d9f75844SAndroid Build Coastguard Worker using ::testing::ElementsAre;
43*d9f75844SAndroid Build Coastguard Worker using ::webrtc::TimeDelta;
44*d9f75844SAndroid Build Coastguard Worker 
45*d9f75844SAndroid Build Coastguard Worker // Generates a sequence of numbers (collaboratively).
46*d9f75844SAndroid Build Coastguard Worker class TestGenerator {
47*d9f75844SAndroid Build Coastguard Worker  public:
TestGenerator()48*d9f75844SAndroid Build Coastguard Worker   TestGenerator() : last(0), count(0) {}
49*d9f75844SAndroid Build Coastguard Worker 
Next(int prev)50*d9f75844SAndroid Build Coastguard Worker   int Next(int prev) {
51*d9f75844SAndroid Build Coastguard Worker     int result = prev + last;
52*d9f75844SAndroid Build Coastguard Worker     last = result;
53*d9f75844SAndroid Build Coastguard Worker     count += 1;
54*d9f75844SAndroid Build Coastguard Worker     return result;
55*d9f75844SAndroid Build Coastguard Worker   }
56*d9f75844SAndroid Build Coastguard Worker 
57*d9f75844SAndroid Build Coastguard Worker   int last;
58*d9f75844SAndroid Build Coastguard Worker   int count;
59*d9f75844SAndroid Build Coastguard Worker };
60*d9f75844SAndroid Build Coastguard Worker 
61*d9f75844SAndroid Build Coastguard Worker // Receives messages and sends on a socket.
62*d9f75844SAndroid Build Coastguard Worker class MessageClient : public TestGenerator {
63*d9f75844SAndroid Build Coastguard Worker  public:
MessageClient(Thread * pth,Socket * socket)64*d9f75844SAndroid Build Coastguard Worker   MessageClient(Thread* pth, Socket* socket) : socket_(socket) {}
65*d9f75844SAndroid Build Coastguard Worker 
~MessageClient()66*d9f75844SAndroid Build Coastguard Worker   ~MessageClient() { delete socket_; }
67*d9f75844SAndroid Build Coastguard Worker 
OnValue(int value)68*d9f75844SAndroid Build Coastguard Worker   void OnValue(int value) {
69*d9f75844SAndroid Build Coastguard Worker     int result = Next(value);
70*d9f75844SAndroid Build Coastguard Worker     EXPECT_GE(socket_->Send(&result, sizeof(result)), 0);
71*d9f75844SAndroid Build Coastguard Worker   }
72*d9f75844SAndroid Build Coastguard Worker 
73*d9f75844SAndroid Build Coastguard Worker  private:
74*d9f75844SAndroid Build Coastguard Worker   Socket* socket_;
75*d9f75844SAndroid Build Coastguard Worker };
76*d9f75844SAndroid Build Coastguard Worker 
77*d9f75844SAndroid Build Coastguard Worker // Receives on a socket and sends by posting messages.
78*d9f75844SAndroid Build Coastguard Worker class SocketClient : public TestGenerator, public sigslot::has_slots<> {
79*d9f75844SAndroid Build Coastguard Worker  public:
SocketClient(Socket * socket,const SocketAddress & addr,Thread * post_thread,MessageClient * phandler)80*d9f75844SAndroid Build Coastguard Worker   SocketClient(Socket* socket,
81*d9f75844SAndroid Build Coastguard Worker                const SocketAddress& addr,
82*d9f75844SAndroid Build Coastguard Worker                Thread* post_thread,
83*d9f75844SAndroid Build Coastguard Worker                MessageClient* phandler)
84*d9f75844SAndroid Build Coastguard Worker       : socket_(AsyncUDPSocket::Create(socket, addr)),
85*d9f75844SAndroid Build Coastguard Worker         post_thread_(post_thread),
86*d9f75844SAndroid Build Coastguard Worker         post_handler_(phandler) {
87*d9f75844SAndroid Build Coastguard Worker     socket_->SignalReadPacket.connect(this, &SocketClient::OnPacket);
88*d9f75844SAndroid Build Coastguard Worker   }
89*d9f75844SAndroid Build Coastguard Worker 
~SocketClient()90*d9f75844SAndroid Build Coastguard Worker   ~SocketClient() override { delete socket_; }
91*d9f75844SAndroid Build Coastguard Worker 
address() const92*d9f75844SAndroid Build Coastguard Worker   SocketAddress address() const { return socket_->GetLocalAddress(); }
93*d9f75844SAndroid Build Coastguard Worker 
OnPacket(AsyncPacketSocket * socket,const char * buf,size_t size,const SocketAddress & remote_addr,const int64_t & packet_time_us)94*d9f75844SAndroid Build Coastguard Worker   void OnPacket(AsyncPacketSocket* socket,
95*d9f75844SAndroid Build Coastguard Worker                 const char* buf,
96*d9f75844SAndroid Build Coastguard Worker                 size_t size,
97*d9f75844SAndroid Build Coastguard Worker                 const SocketAddress& remote_addr,
98*d9f75844SAndroid Build Coastguard Worker                 const int64_t& packet_time_us) {
99*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(size, sizeof(uint32_t));
100*d9f75844SAndroid Build Coastguard Worker     uint32_t prev = reinterpret_cast<const uint32_t*>(buf)[0];
101*d9f75844SAndroid Build Coastguard Worker     uint32_t result = Next(prev);
102*d9f75844SAndroid Build Coastguard Worker 
103*d9f75844SAndroid Build Coastguard Worker     post_thread_->PostDelayedTask([post_handler_ = post_handler_,
104*d9f75844SAndroid Build Coastguard Worker                                    result] { post_handler_->OnValue(result); },
105*d9f75844SAndroid Build Coastguard Worker                                   TimeDelta::Millis(200));
106*d9f75844SAndroid Build Coastguard Worker   }
107*d9f75844SAndroid Build Coastguard Worker 
108*d9f75844SAndroid Build Coastguard Worker  private:
109*d9f75844SAndroid Build Coastguard Worker   AsyncUDPSocket* socket_;
110*d9f75844SAndroid Build Coastguard Worker   Thread* post_thread_;
111*d9f75844SAndroid Build Coastguard Worker   MessageClient* post_handler_;
112*d9f75844SAndroid Build Coastguard Worker };
113*d9f75844SAndroid Build Coastguard Worker 
114*d9f75844SAndroid Build Coastguard Worker class CustomThread : public rtc::Thread {
115*d9f75844SAndroid Build Coastguard Worker  public:
CustomThread()116*d9f75844SAndroid Build Coastguard Worker   CustomThread()
117*d9f75844SAndroid Build Coastguard Worker       : Thread(std::unique_ptr<SocketServer>(new rtc::NullSocketServer())) {}
~CustomThread()118*d9f75844SAndroid Build Coastguard Worker   ~CustomThread() override { Stop(); }
Start()119*d9f75844SAndroid Build Coastguard Worker   bool Start() { return false; }
120*d9f75844SAndroid Build Coastguard Worker 
WrapCurrent()121*d9f75844SAndroid Build Coastguard Worker   bool WrapCurrent() { return Thread::WrapCurrent(); }
UnwrapCurrent()122*d9f75844SAndroid Build Coastguard Worker   void UnwrapCurrent() { Thread::UnwrapCurrent(); }
123*d9f75844SAndroid Build Coastguard Worker };
124*d9f75844SAndroid Build Coastguard Worker 
125*d9f75844SAndroid Build Coastguard Worker // A thread that does nothing when it runs and signals an event
126*d9f75844SAndroid Build Coastguard Worker // when it is destroyed.
127*d9f75844SAndroid Build Coastguard Worker class SignalWhenDestroyedThread : public Thread {
128*d9f75844SAndroid Build Coastguard Worker  public:
SignalWhenDestroyedThread(Event * event)129*d9f75844SAndroid Build Coastguard Worker   SignalWhenDestroyedThread(Event* event)
130*d9f75844SAndroid Build Coastguard Worker       : Thread(std::unique_ptr<SocketServer>(new NullSocketServer())),
131*d9f75844SAndroid Build Coastguard Worker         event_(event) {}
132*d9f75844SAndroid Build Coastguard Worker 
~SignalWhenDestroyedThread()133*d9f75844SAndroid Build Coastguard Worker   ~SignalWhenDestroyedThread() override {
134*d9f75844SAndroid Build Coastguard Worker     Stop();
135*d9f75844SAndroid Build Coastguard Worker     event_->Set();
136*d9f75844SAndroid Build Coastguard Worker   }
137*d9f75844SAndroid Build Coastguard Worker 
Run()138*d9f75844SAndroid Build Coastguard Worker   void Run() override {
139*d9f75844SAndroid Build Coastguard Worker     // Do nothing.
140*d9f75844SAndroid Build Coastguard Worker   }
141*d9f75844SAndroid Build Coastguard Worker 
142*d9f75844SAndroid Build Coastguard Worker  private:
143*d9f75844SAndroid Build Coastguard Worker   Event* event_;
144*d9f75844SAndroid Build Coastguard Worker };
145*d9f75844SAndroid Build Coastguard Worker 
146*d9f75844SAndroid Build Coastguard Worker // See: https://code.google.com/p/webrtc/issues/detail?id=2409
TEST(ThreadTest,DISABLED_Main)147*d9f75844SAndroid Build Coastguard Worker TEST(ThreadTest, DISABLED_Main) {
148*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread main_thread;
149*d9f75844SAndroid Build Coastguard Worker   const SocketAddress addr("127.0.0.1", 0);
150*d9f75844SAndroid Build Coastguard Worker 
151*d9f75844SAndroid Build Coastguard Worker   // Create the messaging client on its own thread.
152*d9f75844SAndroid Build Coastguard Worker   auto th1 = Thread::CreateWithSocketServer();
153*d9f75844SAndroid Build Coastguard Worker   Socket* socket = th1->socketserver()->CreateSocket(addr.family(), SOCK_DGRAM);
154*d9f75844SAndroid Build Coastguard Worker   MessageClient msg_client(th1.get(), socket);
155*d9f75844SAndroid Build Coastguard Worker 
156*d9f75844SAndroid Build Coastguard Worker   // Create the socket client on its own thread.
157*d9f75844SAndroid Build Coastguard Worker   auto th2 = Thread::CreateWithSocketServer();
158*d9f75844SAndroid Build Coastguard Worker   Socket* asocket =
159*d9f75844SAndroid Build Coastguard Worker       th2->socketserver()->CreateSocket(addr.family(), SOCK_DGRAM);
160*d9f75844SAndroid Build Coastguard Worker   SocketClient sock_client(asocket, addr, th1.get(), &msg_client);
161*d9f75844SAndroid Build Coastguard Worker 
162*d9f75844SAndroid Build Coastguard Worker   socket->Connect(sock_client.address());
163*d9f75844SAndroid Build Coastguard Worker 
164*d9f75844SAndroid Build Coastguard Worker   th1->Start();
165*d9f75844SAndroid Build Coastguard Worker   th2->Start();
166*d9f75844SAndroid Build Coastguard Worker 
167*d9f75844SAndroid Build Coastguard Worker   // Get the messages started.
168*d9f75844SAndroid Build Coastguard Worker   th1->PostDelayedTask([&msg_client] { msg_client.OnValue(1); },
169*d9f75844SAndroid Build Coastguard Worker                        TimeDelta::Millis(100));
170*d9f75844SAndroid Build Coastguard Worker 
171*d9f75844SAndroid Build Coastguard Worker   // Give the clients a little while to run.
172*d9f75844SAndroid Build Coastguard Worker   // Messages will be processed at 100, 300, 500, 700, 900.
173*d9f75844SAndroid Build Coastguard Worker   Thread* th_main = Thread::Current();
174*d9f75844SAndroid Build Coastguard Worker   th_main->ProcessMessages(1000);
175*d9f75844SAndroid Build Coastguard Worker 
176*d9f75844SAndroid Build Coastguard Worker   // Stop the sending client. Give the receiver a bit longer to run, in case
177*d9f75844SAndroid Build Coastguard Worker   // it is running on a machine that is under load (e.g. the build machine).
178*d9f75844SAndroid Build Coastguard Worker   th1->Stop();
179*d9f75844SAndroid Build Coastguard Worker   th_main->ProcessMessages(200);
180*d9f75844SAndroid Build Coastguard Worker   th2->Stop();
181*d9f75844SAndroid Build Coastguard Worker 
182*d9f75844SAndroid Build Coastguard Worker   // Make sure the results were correct
183*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(5, msg_client.count);
184*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(34, msg_client.last);
185*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(5, sock_client.count);
186*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(55, sock_client.last);
187*d9f75844SAndroid Build Coastguard Worker }
188*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadTest,CountBlockingCalls)189*d9f75844SAndroid Build Coastguard Worker TEST(ThreadTest, CountBlockingCalls) {
190*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread current;
191*d9f75844SAndroid Build Coastguard Worker 
192*d9f75844SAndroid Build Coastguard Worker   // When the test runs, this will print out:
193*d9f75844SAndroid Build Coastguard Worker   //   (thread_unittest.cc:262): Blocking TestBody: total=2 (actual=1, could=1)
194*d9f75844SAndroid Build Coastguard Worker   RTC_LOG_THREAD_BLOCK_COUNT();
195*d9f75844SAndroid Build Coastguard Worker #if RTC_DCHECK_IS_ON
196*d9f75844SAndroid Build Coastguard Worker   rtc::Thread::ScopedCountBlockingCalls blocked_calls(
197*d9f75844SAndroid Build Coastguard Worker       [&](uint32_t actual_block, uint32_t could_block) {
198*d9f75844SAndroid Build Coastguard Worker         EXPECT_EQ(1u, actual_block);
199*d9f75844SAndroid Build Coastguard Worker         EXPECT_EQ(1u, could_block);
200*d9f75844SAndroid Build Coastguard Worker       });
201*d9f75844SAndroid Build Coastguard Worker 
202*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, blocked_calls.GetBlockingCallCount());
203*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, blocked_calls.GetCouldBeBlockingCallCount());
204*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, blocked_calls.GetTotalBlockedCallCount());
205*d9f75844SAndroid Build Coastguard Worker 
206*d9f75844SAndroid Build Coastguard Worker   // Test invoking on the current thread. This should not count as an 'actual'
207*d9f75844SAndroid Build Coastguard Worker   // invoke, but should still count as an invoke that could block since we
208*d9f75844SAndroid Build Coastguard Worker   // that the call to `BlockingCall` serves a purpose in some configurations
209*d9f75844SAndroid Build Coastguard Worker   // (and should not be used a general way to call methods on the same thread).
210*d9f75844SAndroid Build Coastguard Worker   current.BlockingCall([]() {});
211*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, blocked_calls.GetBlockingCallCount());
212*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, blocked_calls.GetCouldBeBlockingCallCount());
213*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, blocked_calls.GetTotalBlockedCallCount());
214*d9f75844SAndroid Build Coastguard Worker 
215*d9f75844SAndroid Build Coastguard Worker   // Create a new thread to invoke on.
216*d9f75844SAndroid Build Coastguard Worker   auto thread = Thread::CreateWithSocketServer();
217*d9f75844SAndroid Build Coastguard Worker   thread->Start();
218*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(42, thread->BlockingCall([]() { return 42; }));
219*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, blocked_calls.GetBlockingCallCount());
220*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, blocked_calls.GetCouldBeBlockingCallCount());
221*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2u, blocked_calls.GetTotalBlockedCallCount());
222*d9f75844SAndroid Build Coastguard Worker   thread->Stop();
223*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
224*d9f75844SAndroid Build Coastguard Worker #else
225*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(0);
226*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << "Test not active in this config";
227*d9f75844SAndroid Build Coastguard Worker #endif
228*d9f75844SAndroid Build Coastguard Worker }
229*d9f75844SAndroid Build Coastguard Worker 
230*d9f75844SAndroid Build Coastguard Worker #if RTC_DCHECK_IS_ON
TEST(ThreadTest,CountBlockingCallsOneCallback)231*d9f75844SAndroid Build Coastguard Worker TEST(ThreadTest, CountBlockingCallsOneCallback) {
232*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread current;
233*d9f75844SAndroid Build Coastguard Worker   bool was_called_back = false;
234*d9f75844SAndroid Build Coastguard Worker   {
235*d9f75844SAndroid Build Coastguard Worker     rtc::Thread::ScopedCountBlockingCalls blocked_calls(
236*d9f75844SAndroid Build Coastguard Worker         [&](uint32_t actual_block, uint32_t could_block) {
237*d9f75844SAndroid Build Coastguard Worker           was_called_back = true;
238*d9f75844SAndroid Build Coastguard Worker         });
239*d9f75844SAndroid Build Coastguard Worker     current.BlockingCall([]() {});
240*d9f75844SAndroid Build Coastguard Worker   }
241*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(was_called_back);
242*d9f75844SAndroid Build Coastguard Worker }
243*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadTest,CountBlockingCallsSkipCallback)244*d9f75844SAndroid Build Coastguard Worker TEST(ThreadTest, CountBlockingCallsSkipCallback) {
245*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread current;
246*d9f75844SAndroid Build Coastguard Worker   bool was_called_back = false;
247*d9f75844SAndroid Build Coastguard Worker   {
248*d9f75844SAndroid Build Coastguard Worker     rtc::Thread::ScopedCountBlockingCalls blocked_calls(
249*d9f75844SAndroid Build Coastguard Worker         [&](uint32_t actual_block, uint32_t could_block) {
250*d9f75844SAndroid Build Coastguard Worker           was_called_back = true;
251*d9f75844SAndroid Build Coastguard Worker         });
252*d9f75844SAndroid Build Coastguard Worker     // Changed `blocked_calls` to not issue the callback if there are 1 or
253*d9f75844SAndroid Build Coastguard Worker     // fewer blocking calls (i.e. we set the minimum required number to 2).
254*d9f75844SAndroid Build Coastguard Worker     blocked_calls.set_minimum_call_count_for_callback(2);
255*d9f75844SAndroid Build Coastguard Worker     current.BlockingCall([]() {});
256*d9f75844SAndroid Build Coastguard Worker   }
257*d9f75844SAndroid Build Coastguard Worker   // We should not have gotten a call back.
258*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(was_called_back);
259*d9f75844SAndroid Build Coastguard Worker }
260*d9f75844SAndroid Build Coastguard Worker #endif
261*d9f75844SAndroid Build Coastguard Worker 
262*d9f75844SAndroid Build Coastguard Worker // Test that setting thread names doesn't cause a malfunction.
263*d9f75844SAndroid Build Coastguard Worker // There's no easy way to verify the name was set properly at this time.
TEST(ThreadTest,Names)264*d9f75844SAndroid Build Coastguard Worker TEST(ThreadTest, Names) {
265*d9f75844SAndroid Build Coastguard Worker   // Default name
266*d9f75844SAndroid Build Coastguard Worker   auto thread = Thread::CreateWithSocketServer();
267*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(thread->Start());
268*d9f75844SAndroid Build Coastguard Worker   thread->Stop();
269*d9f75844SAndroid Build Coastguard Worker   // Name with no object parameter
270*d9f75844SAndroid Build Coastguard Worker   thread = Thread::CreateWithSocketServer();
271*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(thread->SetName("No object", nullptr));
272*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(thread->Start());
273*d9f75844SAndroid Build Coastguard Worker   thread->Stop();
274*d9f75844SAndroid Build Coastguard Worker   // Really long name
275*d9f75844SAndroid Build Coastguard Worker   thread = Thread::CreateWithSocketServer();
276*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(thread->SetName("Abcdefghijklmnopqrstuvwxyz1234567890", this));
277*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(thread->Start());
278*d9f75844SAndroid Build Coastguard Worker   thread->Stop();
279*d9f75844SAndroid Build Coastguard Worker }
280*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadTest,Wrap)281*d9f75844SAndroid Build Coastguard Worker TEST(ThreadTest, Wrap) {
282*d9f75844SAndroid Build Coastguard Worker   Thread* current_thread = Thread::Current();
283*d9f75844SAndroid Build Coastguard Worker   ThreadManager::Instance()->SetCurrentThread(nullptr);
284*d9f75844SAndroid Build Coastguard Worker 
285*d9f75844SAndroid Build Coastguard Worker   {
286*d9f75844SAndroid Build Coastguard Worker     CustomThread cthread;
287*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(cthread.WrapCurrent());
288*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(&cthread, Thread::Current());
289*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(cthread.RunningForTest());
290*d9f75844SAndroid Build Coastguard Worker     EXPECT_FALSE(cthread.IsOwned());
291*d9f75844SAndroid Build Coastguard Worker     cthread.UnwrapCurrent();
292*d9f75844SAndroid Build Coastguard Worker     EXPECT_FALSE(cthread.RunningForTest());
293*d9f75844SAndroid Build Coastguard Worker   }
294*d9f75844SAndroid Build Coastguard Worker   ThreadManager::Instance()->SetCurrentThread(current_thread);
295*d9f75844SAndroid Build Coastguard Worker }
296*d9f75844SAndroid Build Coastguard Worker 
297*d9f75844SAndroid Build Coastguard Worker #if (!defined(NDEBUG) || RTC_DCHECK_IS_ON)
TEST(ThreadTest,InvokeToThreadAllowedReturnsTrueWithoutPolicies)298*d9f75844SAndroid Build Coastguard Worker TEST(ThreadTest, InvokeToThreadAllowedReturnsTrueWithoutPolicies) {
299*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread main_thread;
300*d9f75844SAndroid Build Coastguard Worker   // Create and start the thread.
301*d9f75844SAndroid Build Coastguard Worker   auto thread1 = Thread::CreateWithSocketServer();
302*d9f75844SAndroid Build Coastguard Worker   auto thread2 = Thread::CreateWithSocketServer();
303*d9f75844SAndroid Build Coastguard Worker 
304*d9f75844SAndroid Build Coastguard Worker   thread1->PostTask(
305*d9f75844SAndroid Build Coastguard Worker       [&]() { EXPECT_TRUE(thread1->IsInvokeToThreadAllowed(thread2.get())); });
306*d9f75844SAndroid Build Coastguard Worker   main_thread.ProcessMessages(100);
307*d9f75844SAndroid Build Coastguard Worker }
308*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadTest,InvokeAllowedWhenThreadsAdded)309*d9f75844SAndroid Build Coastguard Worker TEST(ThreadTest, InvokeAllowedWhenThreadsAdded) {
310*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread main_thread;
311*d9f75844SAndroid Build Coastguard Worker   // Create and start the thread.
312*d9f75844SAndroid Build Coastguard Worker   auto thread1 = Thread::CreateWithSocketServer();
313*d9f75844SAndroid Build Coastguard Worker   auto thread2 = Thread::CreateWithSocketServer();
314*d9f75844SAndroid Build Coastguard Worker   auto thread3 = Thread::CreateWithSocketServer();
315*d9f75844SAndroid Build Coastguard Worker   auto thread4 = Thread::CreateWithSocketServer();
316*d9f75844SAndroid Build Coastguard Worker 
317*d9f75844SAndroid Build Coastguard Worker   thread1->AllowInvokesToThread(thread2.get());
318*d9f75844SAndroid Build Coastguard Worker   thread1->AllowInvokesToThread(thread3.get());
319*d9f75844SAndroid Build Coastguard Worker 
320*d9f75844SAndroid Build Coastguard Worker   thread1->PostTask([&]() {
321*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(thread1->IsInvokeToThreadAllowed(thread2.get()));
322*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(thread1->IsInvokeToThreadAllowed(thread3.get()));
323*d9f75844SAndroid Build Coastguard Worker     EXPECT_FALSE(thread1->IsInvokeToThreadAllowed(thread4.get()));
324*d9f75844SAndroid Build Coastguard Worker   });
325*d9f75844SAndroid Build Coastguard Worker   main_thread.ProcessMessages(100);
326*d9f75844SAndroid Build Coastguard Worker }
327*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadTest,InvokesDisallowedWhenDisallowAllInvokes)328*d9f75844SAndroid Build Coastguard Worker TEST(ThreadTest, InvokesDisallowedWhenDisallowAllInvokes) {
329*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread main_thread;
330*d9f75844SAndroid Build Coastguard Worker   // Create and start the thread.
331*d9f75844SAndroid Build Coastguard Worker   auto thread1 = Thread::CreateWithSocketServer();
332*d9f75844SAndroid Build Coastguard Worker   auto thread2 = Thread::CreateWithSocketServer();
333*d9f75844SAndroid Build Coastguard Worker 
334*d9f75844SAndroid Build Coastguard Worker   thread1->DisallowAllInvokes();
335*d9f75844SAndroid Build Coastguard Worker 
336*d9f75844SAndroid Build Coastguard Worker   thread1->PostTask(
337*d9f75844SAndroid Build Coastguard Worker       [&]() { EXPECT_FALSE(thread1->IsInvokeToThreadAllowed(thread2.get())); });
338*d9f75844SAndroid Build Coastguard Worker   main_thread.ProcessMessages(100);
339*d9f75844SAndroid Build Coastguard Worker }
340*d9f75844SAndroid Build Coastguard Worker #endif  // (!defined(NDEBUG) || RTC_DCHECK_IS_ON)
341*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadTest,InvokesAllowedByDefault)342*d9f75844SAndroid Build Coastguard Worker TEST(ThreadTest, InvokesAllowedByDefault) {
343*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread main_thread;
344*d9f75844SAndroid Build Coastguard Worker   // Create and start the thread.
345*d9f75844SAndroid Build Coastguard Worker   auto thread1 = Thread::CreateWithSocketServer();
346*d9f75844SAndroid Build Coastguard Worker   auto thread2 = Thread::CreateWithSocketServer();
347*d9f75844SAndroid Build Coastguard Worker 
348*d9f75844SAndroid Build Coastguard Worker   thread1->PostTask(
349*d9f75844SAndroid Build Coastguard Worker       [&]() { EXPECT_TRUE(thread1->IsInvokeToThreadAllowed(thread2.get())); });
350*d9f75844SAndroid Build Coastguard Worker   main_thread.ProcessMessages(100);
351*d9f75844SAndroid Build Coastguard Worker }
352*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadTest,BlockingCall)353*d9f75844SAndroid Build Coastguard Worker TEST(ThreadTest, BlockingCall) {
354*d9f75844SAndroid Build Coastguard Worker   // Create and start the thread.
355*d9f75844SAndroid Build Coastguard Worker   auto thread = Thread::CreateWithSocketServer();
356*d9f75844SAndroid Build Coastguard Worker   thread->Start();
357*d9f75844SAndroid Build Coastguard Worker   // Try calling functors.
358*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(42, thread->BlockingCall([] { return 42; }));
359*d9f75844SAndroid Build Coastguard Worker   bool called = false;
360*d9f75844SAndroid Build Coastguard Worker   thread->BlockingCall([&] { called = true; });
361*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(called);
362*d9f75844SAndroid Build Coastguard Worker 
363*d9f75844SAndroid Build Coastguard Worker   // Try calling bare functions.
364*d9f75844SAndroid Build Coastguard Worker   struct LocalFuncs {
365*d9f75844SAndroid Build Coastguard Worker     static int Func1() { return 999; }
366*d9f75844SAndroid Build Coastguard Worker     static void Func2() {}
367*d9f75844SAndroid Build Coastguard Worker   };
368*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(999, thread->BlockingCall(&LocalFuncs::Func1));
369*d9f75844SAndroid Build Coastguard Worker   thread->BlockingCall(&LocalFuncs::Func2);
370*d9f75844SAndroid Build Coastguard Worker }
371*d9f75844SAndroid Build Coastguard Worker 
372*d9f75844SAndroid Build Coastguard Worker // Verifies that two threads calling Invoke on each other at the same time does
373*d9f75844SAndroid Build Coastguard Worker // not deadlock but crash.
374*d9f75844SAndroid Build Coastguard Worker #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
TEST(ThreadTest,TwoThreadsInvokeDeathTest)375*d9f75844SAndroid Build Coastguard Worker TEST(ThreadTest, TwoThreadsInvokeDeathTest) {
376*d9f75844SAndroid Build Coastguard Worker   GTEST_FLAG_SET(death_test_style, "threadsafe");
377*d9f75844SAndroid Build Coastguard Worker   AutoThread thread;
378*d9f75844SAndroid Build Coastguard Worker   Thread* main_thread = Thread::Current();
379*d9f75844SAndroid Build Coastguard Worker   auto other_thread = Thread::CreateWithSocketServer();
380*d9f75844SAndroid Build Coastguard Worker   other_thread->Start();
381*d9f75844SAndroid Build Coastguard Worker   other_thread->BlockingCall([main_thread] {
382*d9f75844SAndroid Build Coastguard Worker     RTC_EXPECT_DEATH(main_thread->BlockingCall([] {}), "loop");
383*d9f75844SAndroid Build Coastguard Worker   });
384*d9f75844SAndroid Build Coastguard Worker }
385*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadTest,ThreeThreadsInvokeDeathTest)386*d9f75844SAndroid Build Coastguard Worker TEST(ThreadTest, ThreeThreadsInvokeDeathTest) {
387*d9f75844SAndroid Build Coastguard Worker   GTEST_FLAG_SET(death_test_style, "threadsafe");
388*d9f75844SAndroid Build Coastguard Worker   AutoThread thread;
389*d9f75844SAndroid Build Coastguard Worker   Thread* first = Thread::Current();
390*d9f75844SAndroid Build Coastguard Worker 
391*d9f75844SAndroid Build Coastguard Worker   auto second = Thread::Create();
392*d9f75844SAndroid Build Coastguard Worker   second->Start();
393*d9f75844SAndroid Build Coastguard Worker   auto third = Thread::Create();
394*d9f75844SAndroid Build Coastguard Worker   third->Start();
395*d9f75844SAndroid Build Coastguard Worker 
396*d9f75844SAndroid Build Coastguard Worker   second->BlockingCall([&] {
397*d9f75844SAndroid Build Coastguard Worker     third->BlockingCall(
398*d9f75844SAndroid Build Coastguard Worker         [&] { RTC_EXPECT_DEATH(first->BlockingCall([] {}), "loop"); });
399*d9f75844SAndroid Build Coastguard Worker   });
400*d9f75844SAndroid Build Coastguard Worker }
401*d9f75844SAndroid Build Coastguard Worker 
402*d9f75844SAndroid Build Coastguard Worker #endif
403*d9f75844SAndroid Build Coastguard Worker 
404*d9f75844SAndroid Build Coastguard Worker // Verifies that if thread A invokes a call on thread B and thread C is trying
405*d9f75844SAndroid Build Coastguard Worker // to invoke A at the same time, thread A does not handle C's invoke while
406*d9f75844SAndroid Build Coastguard Worker // invoking B.
TEST(ThreadTest,ThreeThreadsBlockingCall)407*d9f75844SAndroid Build Coastguard Worker TEST(ThreadTest, ThreeThreadsBlockingCall) {
408*d9f75844SAndroid Build Coastguard Worker   AutoThread thread;
409*d9f75844SAndroid Build Coastguard Worker   Thread* thread_a = Thread::Current();
410*d9f75844SAndroid Build Coastguard Worker   auto thread_b = Thread::CreateWithSocketServer();
411*d9f75844SAndroid Build Coastguard Worker   auto thread_c = Thread::CreateWithSocketServer();
412*d9f75844SAndroid Build Coastguard Worker   thread_b->Start();
413*d9f75844SAndroid Build Coastguard Worker   thread_c->Start();
414*d9f75844SAndroid Build Coastguard Worker 
415*d9f75844SAndroid Build Coastguard Worker   class LockedBool {
416*d9f75844SAndroid Build Coastguard Worker    public:
417*d9f75844SAndroid Build Coastguard Worker     explicit LockedBool(bool value) : value_(value) {}
418*d9f75844SAndroid Build Coastguard Worker 
419*d9f75844SAndroid Build Coastguard Worker     void Set(bool value) {
420*d9f75844SAndroid Build Coastguard Worker       webrtc::MutexLock lock(&mutex_);
421*d9f75844SAndroid Build Coastguard Worker       value_ = value;
422*d9f75844SAndroid Build Coastguard Worker     }
423*d9f75844SAndroid Build Coastguard Worker 
424*d9f75844SAndroid Build Coastguard Worker     bool Get() {
425*d9f75844SAndroid Build Coastguard Worker       webrtc::MutexLock lock(&mutex_);
426*d9f75844SAndroid Build Coastguard Worker       return value_;
427*d9f75844SAndroid Build Coastguard Worker     }
428*d9f75844SAndroid Build Coastguard Worker 
429*d9f75844SAndroid Build Coastguard Worker    private:
430*d9f75844SAndroid Build Coastguard Worker     webrtc::Mutex mutex_;
431*d9f75844SAndroid Build Coastguard Worker     bool value_ RTC_GUARDED_BY(mutex_);
432*d9f75844SAndroid Build Coastguard Worker   };
433*d9f75844SAndroid Build Coastguard Worker 
434*d9f75844SAndroid Build Coastguard Worker   struct LocalFuncs {
435*d9f75844SAndroid Build Coastguard Worker     static void Set(LockedBool* out) { out->Set(true); }
436*d9f75844SAndroid Build Coastguard Worker     static void InvokeSet(Thread* thread, LockedBool* out) {
437*d9f75844SAndroid Build Coastguard Worker       thread->BlockingCall([out] { Set(out); });
438*d9f75844SAndroid Build Coastguard Worker     }
439*d9f75844SAndroid Build Coastguard Worker 
440*d9f75844SAndroid Build Coastguard Worker     // Set `out` true and call InvokeSet on `thread`.
441*d9f75844SAndroid Build Coastguard Worker     static void SetAndInvokeSet(LockedBool* out,
442*d9f75844SAndroid Build Coastguard Worker                                 Thread* thread,
443*d9f75844SAndroid Build Coastguard Worker                                 LockedBool* out_inner) {
444*d9f75844SAndroid Build Coastguard Worker       out->Set(true);
445*d9f75844SAndroid Build Coastguard Worker       InvokeSet(thread, out_inner);
446*d9f75844SAndroid Build Coastguard Worker     }
447*d9f75844SAndroid Build Coastguard Worker 
448*d9f75844SAndroid Build Coastguard Worker     // Asynchronously invoke SetAndInvokeSet on `thread1` and wait until
449*d9f75844SAndroid Build Coastguard Worker     // `thread1` starts the call.
450*d9f75844SAndroid Build Coastguard Worker     static void AsyncInvokeSetAndWait(Thread* thread1,
451*d9f75844SAndroid Build Coastguard Worker                                       Thread* thread2,
452*d9f75844SAndroid Build Coastguard Worker                                       LockedBool* out) {
453*d9f75844SAndroid Build Coastguard Worker       LockedBool async_invoked(false);
454*d9f75844SAndroid Build Coastguard Worker 
455*d9f75844SAndroid Build Coastguard Worker       thread1->PostTask([&async_invoked, thread2, out] {
456*d9f75844SAndroid Build Coastguard Worker         SetAndInvokeSet(&async_invoked, thread2, out);
457*d9f75844SAndroid Build Coastguard Worker       });
458*d9f75844SAndroid Build Coastguard Worker 
459*d9f75844SAndroid Build Coastguard Worker       EXPECT_TRUE_WAIT(async_invoked.Get(), 2000);
460*d9f75844SAndroid Build Coastguard Worker     }
461*d9f75844SAndroid Build Coastguard Worker   };
462*d9f75844SAndroid Build Coastguard Worker 
463*d9f75844SAndroid Build Coastguard Worker   LockedBool thread_a_called(false);
464*d9f75844SAndroid Build Coastguard Worker 
465*d9f75844SAndroid Build Coastguard Worker   // Start the sequence A --(invoke)--> B --(async invoke)--> C --(invoke)--> A.
466*d9f75844SAndroid Build Coastguard Worker   // Thread B returns when C receives the call and C should be blocked until A
467*d9f75844SAndroid Build Coastguard Worker   // starts to process messages.
468*d9f75844SAndroid Build Coastguard Worker   Thread* thread_c_ptr = thread_c.get();
469*d9f75844SAndroid Build Coastguard Worker   thread_b->BlockingCall([thread_c_ptr, thread_a, &thread_a_called] {
470*d9f75844SAndroid Build Coastguard Worker     LocalFuncs::AsyncInvokeSetAndWait(thread_c_ptr, thread_a, &thread_a_called);
471*d9f75844SAndroid Build Coastguard Worker   });
472*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(thread_a_called.Get());
473*d9f75844SAndroid Build Coastguard Worker 
474*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE_WAIT(thread_a_called.Get(), 2000);
475*d9f75844SAndroid Build Coastguard Worker }
476*d9f75844SAndroid Build Coastguard Worker 
DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder(FakeClock & clock,Thread & q)477*d9f75844SAndroid Build Coastguard Worker static void DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder(
478*d9f75844SAndroid Build Coastguard Worker     FakeClock& clock,
479*d9f75844SAndroid Build Coastguard Worker     Thread& q) {
480*d9f75844SAndroid Build Coastguard Worker   std::vector<int> run_order;
481*d9f75844SAndroid Build Coastguard Worker 
482*d9f75844SAndroid Build Coastguard Worker   Event done;
483*d9f75844SAndroid Build Coastguard Worker   int64_t now = TimeMillis();
484*d9f75844SAndroid Build Coastguard Worker   q.PostDelayedTask([&] { run_order.push_back(3); }, TimeDelta::Millis(3));
485*d9f75844SAndroid Build Coastguard Worker   q.PostDelayedTask([&] { run_order.push_back(0); }, TimeDelta::Millis(1));
486*d9f75844SAndroid Build Coastguard Worker   q.PostDelayedTask([&] { run_order.push_back(1); }, TimeDelta::Millis(2));
487*d9f75844SAndroid Build Coastguard Worker   q.PostDelayedTask([&] { run_order.push_back(4); }, TimeDelta::Millis(3));
488*d9f75844SAndroid Build Coastguard Worker   q.PostDelayedTask([&] { run_order.push_back(2); }, TimeDelta::Millis(2));
489*d9f75844SAndroid Build Coastguard Worker   q.PostDelayedTask([&] { done.Set(); }, TimeDelta::Millis(4));
490*d9f75844SAndroid Build Coastguard Worker   // Validate time was frozen while tasks were posted.
491*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_EQ(TimeMillis(), now);
492*d9f75844SAndroid Build Coastguard Worker 
493*d9f75844SAndroid Build Coastguard Worker   // Change time to make all tasks ready to run and wait for them.
494*d9f75844SAndroid Build Coastguard Worker   clock.AdvanceTime(TimeDelta::Millis(4));
495*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(done.Wait(TimeDelta::Seconds(1)));
496*d9f75844SAndroid Build Coastguard Worker 
497*d9f75844SAndroid Build Coastguard Worker   EXPECT_THAT(run_order, ElementsAre(0, 1, 2, 3, 4));
498*d9f75844SAndroid Build Coastguard Worker }
499*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadTest,DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder)500*d9f75844SAndroid Build Coastguard Worker TEST(ThreadTest, DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder) {
501*d9f75844SAndroid Build Coastguard Worker   ScopedBaseFakeClock clock;
502*d9f75844SAndroid Build Coastguard Worker   Thread q(CreateDefaultSocketServer(), true);
503*d9f75844SAndroid Build Coastguard Worker   q.Start();
504*d9f75844SAndroid Build Coastguard Worker   DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder(clock, q);
505*d9f75844SAndroid Build Coastguard Worker 
506*d9f75844SAndroid Build Coastguard Worker   NullSocketServer nullss;
507*d9f75844SAndroid Build Coastguard Worker   Thread q_nullss(&nullss, true);
508*d9f75844SAndroid Build Coastguard Worker   q_nullss.Start();
509*d9f75844SAndroid Build Coastguard Worker   DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder(clock, q_nullss);
510*d9f75844SAndroid Build Coastguard Worker }
511*d9f75844SAndroid Build Coastguard Worker 
512*d9f75844SAndroid Build Coastguard Worker // Ensure that ProcessAllMessageQueues does its essential function; process
513*d9f75844SAndroid Build Coastguard Worker // all messages (both delayed and non delayed) up until the current time, on
514*d9f75844SAndroid Build Coastguard Worker // all registered message queues.
TEST(ThreadManager,ProcessAllMessageQueues)515*d9f75844SAndroid Build Coastguard Worker TEST(ThreadManager, ProcessAllMessageQueues) {
516*d9f75844SAndroid Build Coastguard Worker   rtc::AutoThread main_thread;
517*d9f75844SAndroid Build Coastguard Worker   Event entered_process_all_message_queues(true, false);
518*d9f75844SAndroid Build Coastguard Worker   auto a = Thread::CreateWithSocketServer();
519*d9f75844SAndroid Build Coastguard Worker   auto b = Thread::CreateWithSocketServer();
520*d9f75844SAndroid Build Coastguard Worker   a->Start();
521*d9f75844SAndroid Build Coastguard Worker   b->Start();
522*d9f75844SAndroid Build Coastguard Worker 
523*d9f75844SAndroid Build Coastguard Worker   std::atomic<int> messages_processed(0);
524*d9f75844SAndroid Build Coastguard Worker   auto incrementer = [&messages_processed,
525*d9f75844SAndroid Build Coastguard Worker                       &entered_process_all_message_queues] {
526*d9f75844SAndroid Build Coastguard Worker     // Wait for event as a means to ensure Increment doesn't occur outside
527*d9f75844SAndroid Build Coastguard Worker     // of ProcessAllMessageQueues. The event is set by a message posted to
528*d9f75844SAndroid Build Coastguard Worker     // the main thread, which is guaranteed to be handled inside
529*d9f75844SAndroid Build Coastguard Worker     // ProcessAllMessageQueues.
530*d9f75844SAndroid Build Coastguard Worker     entered_process_all_message_queues.Wait(Event::kForever);
531*d9f75844SAndroid Build Coastguard Worker     messages_processed.fetch_add(1);
532*d9f75844SAndroid Build Coastguard Worker   };
533*d9f75844SAndroid Build Coastguard Worker   auto event_signaler = [&entered_process_all_message_queues] {
534*d9f75844SAndroid Build Coastguard Worker     entered_process_all_message_queues.Set();
535*d9f75844SAndroid Build Coastguard Worker   };
536*d9f75844SAndroid Build Coastguard Worker 
537*d9f75844SAndroid Build Coastguard Worker   // Post messages (both delayed and non delayed) to both threads.
538*d9f75844SAndroid Build Coastguard Worker   a->PostTask(incrementer);
539*d9f75844SAndroid Build Coastguard Worker   b->PostTask(incrementer);
540*d9f75844SAndroid Build Coastguard Worker   a->PostDelayedTask(incrementer, TimeDelta::Zero());
541*d9f75844SAndroid Build Coastguard Worker   b->PostDelayedTask(incrementer, TimeDelta::Zero());
542*d9f75844SAndroid Build Coastguard Worker   main_thread.PostTask(event_signaler);
543*d9f75844SAndroid Build Coastguard Worker 
544*d9f75844SAndroid Build Coastguard Worker   ThreadManager::ProcessAllMessageQueuesForTesting();
545*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(4, messages_processed.load(std::memory_order_acquire));
546*d9f75844SAndroid Build Coastguard Worker }
547*d9f75844SAndroid Build Coastguard Worker 
548*d9f75844SAndroid Build Coastguard Worker // Test that ProcessAllMessageQueues doesn't hang if a thread is quitting.
TEST(ThreadManager,ProcessAllMessageQueuesWithQuittingThread)549*d9f75844SAndroid Build Coastguard Worker TEST(ThreadManager, ProcessAllMessageQueuesWithQuittingThread) {
550*d9f75844SAndroid Build Coastguard Worker   auto t = Thread::CreateWithSocketServer();
551*d9f75844SAndroid Build Coastguard Worker   t->Start();
552*d9f75844SAndroid Build Coastguard Worker   t->Quit();
553*d9f75844SAndroid Build Coastguard Worker   ThreadManager::ProcessAllMessageQueuesForTesting();
554*d9f75844SAndroid Build Coastguard Worker }
555*d9f75844SAndroid Build Coastguard Worker 
WaitAndSetEvent(Event * wait_event,Event * set_event)556*d9f75844SAndroid Build Coastguard Worker void WaitAndSetEvent(Event* wait_event, Event* set_event) {
557*d9f75844SAndroid Build Coastguard Worker   wait_event->Wait(Event::kForever);
558*d9f75844SAndroid Build Coastguard Worker   set_event->Set();
559*d9f75844SAndroid Build Coastguard Worker }
560*d9f75844SAndroid Build Coastguard Worker 
561*d9f75844SAndroid Build Coastguard Worker // A functor that keeps track of the number of copies and moves.
562*d9f75844SAndroid Build Coastguard Worker class LifeCycleFunctor {
563*d9f75844SAndroid Build Coastguard Worker  public:
564*d9f75844SAndroid Build Coastguard Worker   struct Stats {
565*d9f75844SAndroid Build Coastguard Worker     size_t copy_count = 0;
566*d9f75844SAndroid Build Coastguard Worker     size_t move_count = 0;
567*d9f75844SAndroid Build Coastguard Worker   };
568*d9f75844SAndroid Build Coastguard Worker 
LifeCycleFunctor(Stats * stats,Event * event)569*d9f75844SAndroid Build Coastguard Worker   LifeCycleFunctor(Stats* stats, Event* event) : stats_(stats), event_(event) {}
LifeCycleFunctor(const LifeCycleFunctor & other)570*d9f75844SAndroid Build Coastguard Worker   LifeCycleFunctor(const LifeCycleFunctor& other) { *this = other; }
LifeCycleFunctor(LifeCycleFunctor && other)571*d9f75844SAndroid Build Coastguard Worker   LifeCycleFunctor(LifeCycleFunctor&& other) { *this = std::move(other); }
572*d9f75844SAndroid Build Coastguard Worker 
operator =(const LifeCycleFunctor & other)573*d9f75844SAndroid Build Coastguard Worker   LifeCycleFunctor& operator=(const LifeCycleFunctor& other) {
574*d9f75844SAndroid Build Coastguard Worker     stats_ = other.stats_;
575*d9f75844SAndroid Build Coastguard Worker     event_ = other.event_;
576*d9f75844SAndroid Build Coastguard Worker     ++stats_->copy_count;
577*d9f75844SAndroid Build Coastguard Worker     return *this;
578*d9f75844SAndroid Build Coastguard Worker   }
579*d9f75844SAndroid Build Coastguard Worker 
operator =(LifeCycleFunctor && other)580*d9f75844SAndroid Build Coastguard Worker   LifeCycleFunctor& operator=(LifeCycleFunctor&& other) {
581*d9f75844SAndroid Build Coastguard Worker     stats_ = other.stats_;
582*d9f75844SAndroid Build Coastguard Worker     event_ = other.event_;
583*d9f75844SAndroid Build Coastguard Worker     ++stats_->move_count;
584*d9f75844SAndroid Build Coastguard Worker     return *this;
585*d9f75844SAndroid Build Coastguard Worker   }
586*d9f75844SAndroid Build Coastguard Worker 
operator ()()587*d9f75844SAndroid Build Coastguard Worker   void operator()() { event_->Set(); }
588*d9f75844SAndroid Build Coastguard Worker 
589*d9f75844SAndroid Build Coastguard Worker  private:
590*d9f75844SAndroid Build Coastguard Worker   Stats* stats_;
591*d9f75844SAndroid Build Coastguard Worker   Event* event_;
592*d9f75844SAndroid Build Coastguard Worker };
593*d9f75844SAndroid Build Coastguard Worker 
594*d9f75844SAndroid Build Coastguard Worker // A functor that verifies the thread it was destroyed on.
595*d9f75844SAndroid Build Coastguard Worker class DestructionFunctor {
596*d9f75844SAndroid Build Coastguard Worker  public:
DestructionFunctor(Thread * thread,bool * thread_was_current,Event * event)597*d9f75844SAndroid Build Coastguard Worker   DestructionFunctor(Thread* thread, bool* thread_was_current, Event* event)
598*d9f75844SAndroid Build Coastguard Worker       : thread_(thread),
599*d9f75844SAndroid Build Coastguard Worker         thread_was_current_(thread_was_current),
600*d9f75844SAndroid Build Coastguard Worker         event_(event) {}
~DestructionFunctor()601*d9f75844SAndroid Build Coastguard Worker   ~DestructionFunctor() {
602*d9f75844SAndroid Build Coastguard Worker     // Only signal the event if this was the functor that was invoked to avoid
603*d9f75844SAndroid Build Coastguard Worker     // the event being signaled due to the destruction of temporary/moved
604*d9f75844SAndroid Build Coastguard Worker     // versions of this object.
605*d9f75844SAndroid Build Coastguard Worker     if (was_invoked_) {
606*d9f75844SAndroid Build Coastguard Worker       *thread_was_current_ = thread_->IsCurrent();
607*d9f75844SAndroid Build Coastguard Worker       event_->Set();
608*d9f75844SAndroid Build Coastguard Worker     }
609*d9f75844SAndroid Build Coastguard Worker   }
610*d9f75844SAndroid Build Coastguard Worker 
operator ()()611*d9f75844SAndroid Build Coastguard Worker   void operator()() { was_invoked_ = true; }
612*d9f75844SAndroid Build Coastguard Worker 
613*d9f75844SAndroid Build Coastguard Worker  private:
614*d9f75844SAndroid Build Coastguard Worker   Thread* thread_;
615*d9f75844SAndroid Build Coastguard Worker   bool* thread_was_current_;
616*d9f75844SAndroid Build Coastguard Worker   Event* event_;
617*d9f75844SAndroid Build Coastguard Worker   bool was_invoked_ = false;
618*d9f75844SAndroid Build Coastguard Worker };
619*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadPostTaskTest,InvokesWithLambda)620*d9f75844SAndroid Build Coastguard Worker TEST(ThreadPostTaskTest, InvokesWithLambda) {
621*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::Thread> background_thread(rtc::Thread::Create());
622*d9f75844SAndroid Build Coastguard Worker   background_thread->Start();
623*d9f75844SAndroid Build Coastguard Worker 
624*d9f75844SAndroid Build Coastguard Worker   Event event;
625*d9f75844SAndroid Build Coastguard Worker   background_thread->PostTask([&event] { event.Set(); });
626*d9f75844SAndroid Build Coastguard Worker   event.Wait(Event::kForever);
627*d9f75844SAndroid Build Coastguard Worker }
628*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadPostTaskTest,InvokesWithCopiedFunctor)629*d9f75844SAndroid Build Coastguard Worker TEST(ThreadPostTaskTest, InvokesWithCopiedFunctor) {
630*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::Thread> background_thread(rtc::Thread::Create());
631*d9f75844SAndroid Build Coastguard Worker   background_thread->Start();
632*d9f75844SAndroid Build Coastguard Worker 
633*d9f75844SAndroid Build Coastguard Worker   LifeCycleFunctor::Stats stats;
634*d9f75844SAndroid Build Coastguard Worker   Event event;
635*d9f75844SAndroid Build Coastguard Worker   LifeCycleFunctor functor(&stats, &event);
636*d9f75844SAndroid Build Coastguard Worker   background_thread->PostTask(functor);
637*d9f75844SAndroid Build Coastguard Worker   event.Wait(Event::kForever);
638*d9f75844SAndroid Build Coastguard Worker 
639*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, stats.copy_count);
640*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, stats.move_count);
641*d9f75844SAndroid Build Coastguard Worker }
642*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadPostTaskTest,InvokesWithMovedFunctor)643*d9f75844SAndroid Build Coastguard Worker TEST(ThreadPostTaskTest, InvokesWithMovedFunctor) {
644*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::Thread> background_thread(rtc::Thread::Create());
645*d9f75844SAndroid Build Coastguard Worker   background_thread->Start();
646*d9f75844SAndroid Build Coastguard Worker 
647*d9f75844SAndroid Build Coastguard Worker   LifeCycleFunctor::Stats stats;
648*d9f75844SAndroid Build Coastguard Worker   Event event;
649*d9f75844SAndroid Build Coastguard Worker   LifeCycleFunctor functor(&stats, &event);
650*d9f75844SAndroid Build Coastguard Worker   background_thread->PostTask(std::move(functor));
651*d9f75844SAndroid Build Coastguard Worker   event.Wait(Event::kForever);
652*d9f75844SAndroid Build Coastguard Worker 
653*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, stats.copy_count);
654*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, stats.move_count);
655*d9f75844SAndroid Build Coastguard Worker }
656*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadPostTaskTest,InvokesWithReferencedFunctorShouldCopy)657*d9f75844SAndroid Build Coastguard Worker TEST(ThreadPostTaskTest, InvokesWithReferencedFunctorShouldCopy) {
658*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::Thread> background_thread(rtc::Thread::Create());
659*d9f75844SAndroid Build Coastguard Worker   background_thread->Start();
660*d9f75844SAndroid Build Coastguard Worker 
661*d9f75844SAndroid Build Coastguard Worker   LifeCycleFunctor::Stats stats;
662*d9f75844SAndroid Build Coastguard Worker   Event event;
663*d9f75844SAndroid Build Coastguard Worker   LifeCycleFunctor functor(&stats, &event);
664*d9f75844SAndroid Build Coastguard Worker   LifeCycleFunctor& functor_ref = functor;
665*d9f75844SAndroid Build Coastguard Worker   background_thread->PostTask(functor_ref);
666*d9f75844SAndroid Build Coastguard Worker   event.Wait(Event::kForever);
667*d9f75844SAndroid Build Coastguard Worker 
668*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1u, stats.copy_count);
669*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0u, stats.move_count);
670*d9f75844SAndroid Build Coastguard Worker }
671*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadPostTaskTest,InvokesWithCopiedFunctorDestroyedOnTargetThread)672*d9f75844SAndroid Build Coastguard Worker TEST(ThreadPostTaskTest, InvokesWithCopiedFunctorDestroyedOnTargetThread) {
673*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::Thread> background_thread(rtc::Thread::Create());
674*d9f75844SAndroid Build Coastguard Worker   background_thread->Start();
675*d9f75844SAndroid Build Coastguard Worker 
676*d9f75844SAndroid Build Coastguard Worker   Event event;
677*d9f75844SAndroid Build Coastguard Worker   bool was_invoked_on_background_thread = false;
678*d9f75844SAndroid Build Coastguard Worker   DestructionFunctor functor(background_thread.get(),
679*d9f75844SAndroid Build Coastguard Worker                              &was_invoked_on_background_thread, &event);
680*d9f75844SAndroid Build Coastguard Worker   background_thread->PostTask(functor);
681*d9f75844SAndroid Build Coastguard Worker   event.Wait(Event::kForever);
682*d9f75844SAndroid Build Coastguard Worker 
683*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(was_invoked_on_background_thread);
684*d9f75844SAndroid Build Coastguard Worker }
685*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadPostTaskTest,InvokesWithMovedFunctorDestroyedOnTargetThread)686*d9f75844SAndroid Build Coastguard Worker TEST(ThreadPostTaskTest, InvokesWithMovedFunctorDestroyedOnTargetThread) {
687*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::Thread> background_thread(rtc::Thread::Create());
688*d9f75844SAndroid Build Coastguard Worker   background_thread->Start();
689*d9f75844SAndroid Build Coastguard Worker 
690*d9f75844SAndroid Build Coastguard Worker   Event event;
691*d9f75844SAndroid Build Coastguard Worker   bool was_invoked_on_background_thread = false;
692*d9f75844SAndroid Build Coastguard Worker   DestructionFunctor functor(background_thread.get(),
693*d9f75844SAndroid Build Coastguard Worker                              &was_invoked_on_background_thread, &event);
694*d9f75844SAndroid Build Coastguard Worker   background_thread->PostTask(std::move(functor));
695*d9f75844SAndroid Build Coastguard Worker   event.Wait(Event::kForever);
696*d9f75844SAndroid Build Coastguard Worker 
697*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(was_invoked_on_background_thread);
698*d9f75844SAndroid Build Coastguard Worker }
699*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadPostTaskTest,InvokesWithReferencedFunctorShouldCopyAndDestroyedOnTargetThread)700*d9f75844SAndroid Build Coastguard Worker TEST(ThreadPostTaskTest,
701*d9f75844SAndroid Build Coastguard Worker      InvokesWithReferencedFunctorShouldCopyAndDestroyedOnTargetThread) {
702*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::Thread> background_thread(rtc::Thread::Create());
703*d9f75844SAndroid Build Coastguard Worker   background_thread->Start();
704*d9f75844SAndroid Build Coastguard Worker 
705*d9f75844SAndroid Build Coastguard Worker   Event event;
706*d9f75844SAndroid Build Coastguard Worker   bool was_invoked_on_background_thread = false;
707*d9f75844SAndroid Build Coastguard Worker   DestructionFunctor functor(background_thread.get(),
708*d9f75844SAndroid Build Coastguard Worker                              &was_invoked_on_background_thread, &event);
709*d9f75844SAndroid Build Coastguard Worker   DestructionFunctor& functor_ref = functor;
710*d9f75844SAndroid Build Coastguard Worker   background_thread->PostTask(functor_ref);
711*d9f75844SAndroid Build Coastguard Worker   event.Wait(Event::kForever);
712*d9f75844SAndroid Build Coastguard Worker 
713*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(was_invoked_on_background_thread);
714*d9f75844SAndroid Build Coastguard Worker }
715*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadPostTaskTest,InvokesOnBackgroundThread)716*d9f75844SAndroid Build Coastguard Worker TEST(ThreadPostTaskTest, InvokesOnBackgroundThread) {
717*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::Thread> background_thread(rtc::Thread::Create());
718*d9f75844SAndroid Build Coastguard Worker   background_thread->Start();
719*d9f75844SAndroid Build Coastguard Worker 
720*d9f75844SAndroid Build Coastguard Worker   Event event;
721*d9f75844SAndroid Build Coastguard Worker   bool was_invoked_on_background_thread = false;
722*d9f75844SAndroid Build Coastguard Worker   Thread* background_thread_ptr = background_thread.get();
723*d9f75844SAndroid Build Coastguard Worker   background_thread->PostTask(
724*d9f75844SAndroid Build Coastguard Worker       [background_thread_ptr, &was_invoked_on_background_thread, &event] {
725*d9f75844SAndroid Build Coastguard Worker         was_invoked_on_background_thread = background_thread_ptr->IsCurrent();
726*d9f75844SAndroid Build Coastguard Worker         event.Set();
727*d9f75844SAndroid Build Coastguard Worker       });
728*d9f75844SAndroid Build Coastguard Worker   event.Wait(Event::kForever);
729*d9f75844SAndroid Build Coastguard Worker 
730*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(was_invoked_on_background_thread);
731*d9f75844SAndroid Build Coastguard Worker }
732*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadPostTaskTest,InvokesAsynchronously)733*d9f75844SAndroid Build Coastguard Worker TEST(ThreadPostTaskTest, InvokesAsynchronously) {
734*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::Thread> background_thread(rtc::Thread::Create());
735*d9f75844SAndroid Build Coastguard Worker   background_thread->Start();
736*d9f75844SAndroid Build Coastguard Worker 
737*d9f75844SAndroid Build Coastguard Worker   // The first event ensures that SendSingleMessage() is not blocking this
738*d9f75844SAndroid Build Coastguard Worker   // thread. The second event ensures that the message is processed.
739*d9f75844SAndroid Build Coastguard Worker   Event event_set_by_test_thread;
740*d9f75844SAndroid Build Coastguard Worker   Event event_set_by_background_thread;
741*d9f75844SAndroid Build Coastguard Worker   background_thread->PostTask(
742*d9f75844SAndroid Build Coastguard Worker       [&event_set_by_test_thread, &event_set_by_background_thread] {
743*d9f75844SAndroid Build Coastguard Worker         WaitAndSetEvent(&event_set_by_test_thread,
744*d9f75844SAndroid Build Coastguard Worker                         &event_set_by_background_thread);
745*d9f75844SAndroid Build Coastguard Worker       });
746*d9f75844SAndroid Build Coastguard Worker   event_set_by_test_thread.Set();
747*d9f75844SAndroid Build Coastguard Worker   event_set_by_background_thread.Wait(Event::kForever);
748*d9f75844SAndroid Build Coastguard Worker }
749*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadPostTaskTest,InvokesInPostedOrder)750*d9f75844SAndroid Build Coastguard Worker TEST(ThreadPostTaskTest, InvokesInPostedOrder) {
751*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::Thread> background_thread(rtc::Thread::Create());
752*d9f75844SAndroid Build Coastguard Worker   background_thread->Start();
753*d9f75844SAndroid Build Coastguard Worker 
754*d9f75844SAndroid Build Coastguard Worker   Event first;
755*d9f75844SAndroid Build Coastguard Worker   Event second;
756*d9f75844SAndroid Build Coastguard Worker   Event third;
757*d9f75844SAndroid Build Coastguard Worker   Event fourth;
758*d9f75844SAndroid Build Coastguard Worker 
759*d9f75844SAndroid Build Coastguard Worker   background_thread->PostTask(
760*d9f75844SAndroid Build Coastguard Worker       [&first, &second] { WaitAndSetEvent(&first, &second); });
761*d9f75844SAndroid Build Coastguard Worker   background_thread->PostTask(
762*d9f75844SAndroid Build Coastguard Worker       [&second, &third] { WaitAndSetEvent(&second, &third); });
763*d9f75844SAndroid Build Coastguard Worker   background_thread->PostTask(
764*d9f75844SAndroid Build Coastguard Worker       [&third, &fourth] { WaitAndSetEvent(&third, &fourth); });
765*d9f75844SAndroid Build Coastguard Worker 
766*d9f75844SAndroid Build Coastguard Worker   // All tasks have been posted before the first one is unblocked.
767*d9f75844SAndroid Build Coastguard Worker   first.Set();
768*d9f75844SAndroid Build Coastguard Worker   // Only if the chain is invoked in posted order will the last event be set.
769*d9f75844SAndroid Build Coastguard Worker   fourth.Wait(Event::kForever);
770*d9f75844SAndroid Build Coastguard Worker }
771*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadPostDelayedTaskTest,InvokesAsynchronously)772*d9f75844SAndroid Build Coastguard Worker TEST(ThreadPostDelayedTaskTest, InvokesAsynchronously) {
773*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::Thread> background_thread(rtc::Thread::Create());
774*d9f75844SAndroid Build Coastguard Worker   background_thread->Start();
775*d9f75844SAndroid Build Coastguard Worker 
776*d9f75844SAndroid Build Coastguard Worker   // The first event ensures that SendSingleMessage() is not blocking this
777*d9f75844SAndroid Build Coastguard Worker   // thread. The second event ensures that the message is processed.
778*d9f75844SAndroid Build Coastguard Worker   Event event_set_by_test_thread;
779*d9f75844SAndroid Build Coastguard Worker   Event event_set_by_background_thread;
780*d9f75844SAndroid Build Coastguard Worker   background_thread->PostDelayedTask(
781*d9f75844SAndroid Build Coastguard Worker       [&event_set_by_test_thread, &event_set_by_background_thread] {
782*d9f75844SAndroid Build Coastguard Worker         WaitAndSetEvent(&event_set_by_test_thread,
783*d9f75844SAndroid Build Coastguard Worker                         &event_set_by_background_thread);
784*d9f75844SAndroid Build Coastguard Worker       },
785*d9f75844SAndroid Build Coastguard Worker       TimeDelta::Millis(10));
786*d9f75844SAndroid Build Coastguard Worker   event_set_by_test_thread.Set();
787*d9f75844SAndroid Build Coastguard Worker   event_set_by_background_thread.Wait(Event::kForever);
788*d9f75844SAndroid Build Coastguard Worker }
789*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadPostDelayedTaskTest,InvokesInDelayOrder)790*d9f75844SAndroid Build Coastguard Worker TEST(ThreadPostDelayedTaskTest, InvokesInDelayOrder) {
791*d9f75844SAndroid Build Coastguard Worker   ScopedFakeClock clock;
792*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::Thread> background_thread(rtc::Thread::Create());
793*d9f75844SAndroid Build Coastguard Worker   background_thread->Start();
794*d9f75844SAndroid Build Coastguard Worker 
795*d9f75844SAndroid Build Coastguard Worker   Event first;
796*d9f75844SAndroid Build Coastguard Worker   Event second;
797*d9f75844SAndroid Build Coastguard Worker   Event third;
798*d9f75844SAndroid Build Coastguard Worker   Event fourth;
799*d9f75844SAndroid Build Coastguard Worker 
800*d9f75844SAndroid Build Coastguard Worker   background_thread->PostDelayedTask(
801*d9f75844SAndroid Build Coastguard Worker       [&third, &fourth] { WaitAndSetEvent(&third, &fourth); },
802*d9f75844SAndroid Build Coastguard Worker       TimeDelta::Millis(11));
803*d9f75844SAndroid Build Coastguard Worker   background_thread->PostDelayedTask(
804*d9f75844SAndroid Build Coastguard Worker       [&first, &second] { WaitAndSetEvent(&first, &second); },
805*d9f75844SAndroid Build Coastguard Worker       TimeDelta::Millis(9));
806*d9f75844SAndroid Build Coastguard Worker   background_thread->PostDelayedTask(
807*d9f75844SAndroid Build Coastguard Worker       [&second, &third] { WaitAndSetEvent(&second, &third); },
808*d9f75844SAndroid Build Coastguard Worker       TimeDelta::Millis(10));
809*d9f75844SAndroid Build Coastguard Worker 
810*d9f75844SAndroid Build Coastguard Worker   // All tasks have been posted before the first one is unblocked.
811*d9f75844SAndroid Build Coastguard Worker   first.Set();
812*d9f75844SAndroid Build Coastguard Worker   // Only if the chain is invoked in delay order will the last event be set.
813*d9f75844SAndroid Build Coastguard Worker   clock.AdvanceTime(TimeDelta::Millis(11));
814*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(fourth.Wait(TimeDelta::Zero()));
815*d9f75844SAndroid Build Coastguard Worker }
816*d9f75844SAndroid Build Coastguard Worker 
TEST(ThreadPostDelayedTaskTest,IsCurrentTaskQueue)817*d9f75844SAndroid Build Coastguard Worker TEST(ThreadPostDelayedTaskTest, IsCurrentTaskQueue) {
818*d9f75844SAndroid Build Coastguard Worker   auto current_tq = webrtc::TaskQueueBase::Current();
819*d9f75844SAndroid Build Coastguard Worker   {
820*d9f75844SAndroid Build Coastguard Worker     std::unique_ptr<rtc::Thread> thread(rtc::Thread::Create());
821*d9f75844SAndroid Build Coastguard Worker     thread->WrapCurrent();
822*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(webrtc::TaskQueueBase::Current(),
823*d9f75844SAndroid Build Coastguard Worker               static_cast<webrtc::TaskQueueBase*>(thread.get()));
824*d9f75844SAndroid Build Coastguard Worker     thread->UnwrapCurrent();
825*d9f75844SAndroid Build Coastguard Worker   }
826*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(webrtc::TaskQueueBase::Current(), current_tq);
827*d9f75844SAndroid Build Coastguard Worker }
828*d9f75844SAndroid Build Coastguard Worker 
829*d9f75844SAndroid Build Coastguard Worker class ThreadFactory : public webrtc::TaskQueueFactory {
830*d9f75844SAndroid Build Coastguard Worker  public:
831*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<webrtc::TaskQueueBase, webrtc::TaskQueueDeleter>
CreateTaskQueue(absl::string_view,Priority) const832*d9f75844SAndroid Build Coastguard Worker   CreateTaskQueue(absl::string_view /* name */,
833*d9f75844SAndroid Build Coastguard Worker                   Priority /*priority*/) const override {
834*d9f75844SAndroid Build Coastguard Worker     std::unique_ptr<Thread> thread = Thread::Create();
835*d9f75844SAndroid Build Coastguard Worker     thread->Start();
836*d9f75844SAndroid Build Coastguard Worker     return std::unique_ptr<webrtc::TaskQueueBase, webrtc::TaskQueueDeleter>(
837*d9f75844SAndroid Build Coastguard Worker         thread.release());
838*d9f75844SAndroid Build Coastguard Worker   }
839*d9f75844SAndroid Build Coastguard Worker };
840*d9f75844SAndroid Build Coastguard Worker 
CreateDefaultThreadFactory(const webrtc::FieldTrialsView *)841*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<webrtc::TaskQueueFactory> CreateDefaultThreadFactory(
842*d9f75844SAndroid Build Coastguard Worker     const webrtc::FieldTrialsView*) {
843*d9f75844SAndroid Build Coastguard Worker   return std::make_unique<ThreadFactory>();
844*d9f75844SAndroid Build Coastguard Worker }
845*d9f75844SAndroid Build Coastguard Worker 
846*d9f75844SAndroid Build Coastguard Worker using ::webrtc::TaskQueueTest;
847*d9f75844SAndroid Build Coastguard Worker 
848*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(RtcThread,
849*d9f75844SAndroid Build Coastguard Worker                          TaskQueueTest,
850*d9f75844SAndroid Build Coastguard Worker                          ::testing::Values(CreateDefaultThreadFactory));
851*d9f75844SAndroid Build Coastguard Worker 
852*d9f75844SAndroid Build Coastguard Worker }  // namespace
853*d9f75844SAndroid Build Coastguard Worker }  // namespace rtc
854