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