| /* | |
| * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | |
| * | |
| * Use of this source code is governed by a BSD-style license | |
| * that can be found in the LICENSE file in the root of the source | |
| * tree. An additional intellectual property rights grant can be found | |
| * in the file PATENTS. All contributing project authors may | |
| * be found in the AUTHORS file in the root of the source tree. | |
| */ | |
| #include "rtc_base/platform_thread.h" | |
| #include "absl/types/optional.h" | |
| #include "rtc_base/event.h" | |
| #include "system_wrappers/include/sleep.h" | |
| #include "test/gmock.h" | |
| namespace rtc { | |
| TEST(PlatformThreadTest, DefaultConstructedIsEmpty) { | |
| PlatformThread thread; | |
| EXPECT_EQ(thread.GetHandle(), absl::nullopt); | |
| EXPECT_TRUE(thread.empty()); | |
| } | |
| TEST(PlatformThreadTest, StartFinalize) { | |
| PlatformThread thread = PlatformThread::SpawnJoinable([] {}, "1"); | |
| EXPECT_NE(thread.GetHandle(), absl::nullopt); | |
| EXPECT_FALSE(thread.empty()); | |
| thread.Finalize(); | |
| EXPECT_TRUE(thread.empty()); | |
| rtc::Event done; | |
| thread = PlatformThread::SpawnDetached([&] { done.Set(); }, "2"); | |
| EXPECT_FALSE(thread.empty()); | |
| thread.Finalize(); | |
| EXPECT_TRUE(thread.empty()); | |
| done.Wait(webrtc::TimeDelta::Seconds(30)); | |
| } | |
| TEST(PlatformThreadTest, MovesEmpty) { | |
| PlatformThread thread1; | |
| PlatformThread thread2 = std::move(thread1); | |
| EXPECT_TRUE(thread1.empty()); | |
| EXPECT_TRUE(thread2.empty()); | |
| } | |
| TEST(PlatformThreadTest, MovesHandles) { | |
| PlatformThread thread1 = PlatformThread::SpawnJoinable([] {}, "1"); | |
| PlatformThread thread2 = std::move(thread1); | |
| EXPECT_TRUE(thread1.empty()); | |
| EXPECT_FALSE(thread2.empty()); | |
| rtc::Event done; | |
| thread1 = PlatformThread::SpawnDetached([&] { done.Set(); }, "2"); | |
| thread2 = std::move(thread1); | |
| EXPECT_TRUE(thread1.empty()); | |
| EXPECT_FALSE(thread2.empty()); | |
| done.Wait(webrtc::TimeDelta::Seconds(30)); | |
| } | |
| TEST(PlatformThreadTest, | |
| TwoThreadHandlesAreDifferentWhenStartedAndEqualWhenJoined) { | |
| PlatformThread thread1 = PlatformThread(); | |
| PlatformThread thread2 = PlatformThread(); | |
| EXPECT_EQ(thread1.GetHandle(), thread2.GetHandle()); | |
| thread1 = PlatformThread::SpawnJoinable([] {}, "1"); | |
| thread2 = PlatformThread::SpawnJoinable([] {}, "2"); | |
| EXPECT_NE(thread1.GetHandle(), thread2.GetHandle()); | |
| thread1.Finalize(); | |
| EXPECT_NE(thread1.GetHandle(), thread2.GetHandle()); | |
| thread2.Finalize(); | |
| EXPECT_EQ(thread1.GetHandle(), thread2.GetHandle()); | |
| } | |
| TEST(PlatformThreadTest, RunFunctionIsCalled) { | |
| bool flag = false; | |
| PlatformThread::SpawnJoinable([&] { flag = true; }, "T"); | |
| EXPECT_TRUE(flag); | |
| } | |
| TEST(PlatformThreadTest, JoinsThread) { | |
| // This test flakes if there are problems with the join implementation. | |
| rtc::Event event; | |
| PlatformThread::SpawnJoinable([&] { event.Set(); }, "T"); | |
| EXPECT_TRUE(event.Wait(/*give_up_after=*/webrtc::TimeDelta::Zero())); | |
| } | |
| TEST(PlatformThreadTest, StopsBeforeDetachedThreadExits) { | |
| // This test flakes if there are problems with the detached thread | |
| // implementation. | |
| bool flag = false; | |
| rtc::Event thread_started; | |
| rtc::Event thread_continue; | |
| rtc::Event thread_exiting; | |
| PlatformThread::SpawnDetached( | |
| [&] { | |
| thread_started.Set(); | |
| thread_continue.Wait(Event::kForever); | |
| flag = true; | |
| thread_exiting.Set(); | |
| }, | |
| "T"); | |
| thread_started.Wait(Event::kForever); | |
| EXPECT_FALSE(flag); | |
| thread_continue.Set(); | |
| thread_exiting.Wait(Event::kForever); | |
| EXPECT_TRUE(flag); | |
| } | |
| } // namespace rtc |