blob: be4417a05093a0e66c0125fa5bed0b8417bfd0ba [file] [log] [blame]
/*
* 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 <optional>
#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(), std::nullopt);
EXPECT_TRUE(thread.empty());
}
TEST(PlatformThreadTest, StartFinalize) {
PlatformThread thread = PlatformThread::SpawnJoinable([] {}, "1");
EXPECT_NE(thread.GetHandle(), std::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