1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "rtc_base/platform_thread.h"
12
13 #include "absl/types/optional.h"
14 #include "rtc_base/event.h"
15 #include "system_wrappers/include/sleep.h"
16 #include "test/gmock.h"
17
18 namespace rtc {
19
TEST(PlatformThreadTest,DefaultConstructedIsEmpty)20 TEST(PlatformThreadTest, DefaultConstructedIsEmpty) {
21 PlatformThread thread;
22 EXPECT_EQ(thread.GetHandle(), absl::nullopt);
23 EXPECT_TRUE(thread.empty());
24 }
25
TEST(PlatformThreadTest,StartFinalize)26 TEST(PlatformThreadTest, StartFinalize) {
27 PlatformThread thread = PlatformThread::SpawnJoinable([] {}, "1");
28 EXPECT_NE(thread.GetHandle(), absl::nullopt);
29 EXPECT_FALSE(thread.empty());
30 thread.Finalize();
31 EXPECT_TRUE(thread.empty());
32 rtc::Event done;
33 thread = PlatformThread::SpawnDetached([&] { done.Set(); }, "2");
34 EXPECT_FALSE(thread.empty());
35 thread.Finalize();
36 EXPECT_TRUE(thread.empty());
37 done.Wait(webrtc::TimeDelta::Seconds(30));
38 }
39
TEST(PlatformThreadTest,MovesEmpty)40 TEST(PlatformThreadTest, MovesEmpty) {
41 PlatformThread thread1;
42 PlatformThread thread2 = std::move(thread1);
43 EXPECT_TRUE(thread1.empty());
44 EXPECT_TRUE(thread2.empty());
45 }
46
TEST(PlatformThreadTest,MovesHandles)47 TEST(PlatformThreadTest, MovesHandles) {
48 PlatformThread thread1 = PlatformThread::SpawnJoinable([] {}, "1");
49 PlatformThread thread2 = std::move(thread1);
50 EXPECT_TRUE(thread1.empty());
51 EXPECT_FALSE(thread2.empty());
52 rtc::Event done;
53 thread1 = PlatformThread::SpawnDetached([&] { done.Set(); }, "2");
54 thread2 = std::move(thread1);
55 EXPECT_TRUE(thread1.empty());
56 EXPECT_FALSE(thread2.empty());
57 done.Wait(webrtc::TimeDelta::Seconds(30));
58 }
59
TEST(PlatformThreadTest,TwoThreadHandlesAreDifferentWhenStartedAndEqualWhenJoined)60 TEST(PlatformThreadTest,
61 TwoThreadHandlesAreDifferentWhenStartedAndEqualWhenJoined) {
62 PlatformThread thread1 = PlatformThread();
63 PlatformThread thread2 = PlatformThread();
64 EXPECT_EQ(thread1.GetHandle(), thread2.GetHandle());
65 thread1 = PlatformThread::SpawnJoinable([] {}, "1");
66 thread2 = PlatformThread::SpawnJoinable([] {}, "2");
67 EXPECT_NE(thread1.GetHandle(), thread2.GetHandle());
68 thread1.Finalize();
69 EXPECT_NE(thread1.GetHandle(), thread2.GetHandle());
70 thread2.Finalize();
71 EXPECT_EQ(thread1.GetHandle(), thread2.GetHandle());
72 }
73
TEST(PlatformThreadTest,RunFunctionIsCalled)74 TEST(PlatformThreadTest, RunFunctionIsCalled) {
75 bool flag = false;
76 PlatformThread::SpawnJoinable([&] { flag = true; }, "T");
77 EXPECT_TRUE(flag);
78 }
79
TEST(PlatformThreadTest,JoinsThread)80 TEST(PlatformThreadTest, JoinsThread) {
81 // This test flakes if there are problems with the join implementation.
82 rtc::Event event;
83 PlatformThread::SpawnJoinable([&] { event.Set(); }, "T");
84 EXPECT_TRUE(event.Wait(/*give_up_after=*/webrtc::TimeDelta::Zero()));
85 }
86
TEST(PlatformThreadTest,StopsBeforeDetachedThreadExits)87 TEST(PlatformThreadTest, StopsBeforeDetachedThreadExits) {
88 // This test flakes if there are problems with the detached thread
89 // implementation.
90 bool flag = false;
91 rtc::Event thread_started;
92 rtc::Event thread_continue;
93 rtc::Event thread_exiting;
94 PlatformThread::SpawnDetached(
95 [&] {
96 thread_started.Set();
97 thread_continue.Wait(Event::kForever);
98 flag = true;
99 thread_exiting.Set();
100 },
101 "T");
102 thread_started.Wait(Event::kForever);
103 EXPECT_FALSE(flag);
104 thread_continue.Set();
105 thread_exiting.Wait(Event::kForever);
106 EXPECT_TRUE(flag);
107 }
108
109 } // namespace rtc
110