#include "base/task/single_thread_task_runner.h"
#include "base/barrier_closure.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/test/bind.h"
#include "base/test/gtest_util.h"
#include "base/test/task_environment.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread_checker.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
TEST(SingleThreadTaskRunnerCurrentDefaultHandleTest, Basic) {
scoped_refptr<SingleThreadTaskRunner> task_runner(
MakeRefCounted<TestSimpleTaskRunner>());
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
{
SingleThreadTaskRunner::CurrentDefaultHandle sttcd1(task_runner);
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner, SingleThreadTaskRunner::GetCurrentDefault());
}
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
}
TEST(SingleThreadTaskRunnerCurrentDefaultHandleTest, DeathOnImplicitOverride) {
scoped_refptr<SingleThreadTaskRunner> task_runner(
MakeRefCounted<TestSimpleTaskRunner>());
scoped_refptr<SingleThreadTaskRunner> overidding_task_runner(
MakeRefCounted<TestSimpleTaskRunner>());
SingleThreadTaskRunner::CurrentDefaultHandle sttcd(task_runner);
EXPECT_CHECK_DEATH({
SingleThreadTaskRunner::CurrentDefaultHandle overriding_sttcd(
overidding_task_runner);
});
}
TEST(SingleThreadTaskRunnerCurrentDefaultHandleTest, NestedOverrideForTesting) {
scoped_refptr<SingleThreadTaskRunner> task_runner_1(
MakeRefCounted<TestSimpleTaskRunner>());
scoped_refptr<SingleThreadTaskRunner> task_runner_2(
MakeRefCounted<TestSimpleTaskRunner>());
scoped_refptr<SingleThreadTaskRunner> task_runner_3(
MakeRefCounted<TestSimpleTaskRunner>());
scoped_refptr<SingleThreadTaskRunner> task_runner_4(
MakeRefCounted<TestSimpleTaskRunner>());
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
{
SingleThreadTaskRunner::CurrentDefaultHandle sttcd1(task_runner_1);
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner_1, SingleThreadTaskRunner::GetCurrentDefault());
{
SingleThreadTaskRunner::CurrentHandleOverrideForTesting sttcd_override_2(
task_runner_2);
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner_2, SingleThreadTaskRunner::GetCurrentDefault());
{
SingleThreadTaskRunner::CurrentHandleOverrideForTesting
sttcd_override_3(task_runner_3);
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner_3, SingleThreadTaskRunner::GetCurrentDefault());
}
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner_2, SingleThreadTaskRunner::GetCurrentDefault());
{
SingleThreadTaskRunner::CurrentHandleOverrideForTesting
sttcd_override_4(task_runner_4);
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner_4, SingleThreadTaskRunner::GetCurrentDefault());
}
}
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner_1, SingleThreadTaskRunner::GetCurrentDefault());
}
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
}
TEST(SingleThreadTaskRunnerCurrentDefaultHandleTest,
NestedOverrideWithMayAlreadyExist) {
scoped_refptr<SingleThreadTaskRunner> task_runner_1(
MakeRefCounted<TestSimpleTaskRunner>());
scoped_refptr<SingleThreadTaskRunner> task_runner_2(
MakeRefCounted<TestSimpleTaskRunner>());
scoped_refptr<SingleThreadTaskRunner> task_runner_3(
MakeRefCounted<TestSimpleTaskRunner>());
scoped_refptr<SingleThreadTaskRunner> task_runner_4(
MakeRefCounted<TestSimpleTaskRunner>());
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
{
SingleThreadTaskRunner::CurrentDefaultHandle sttcd1(task_runner_1);
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner_1, SingleThreadTaskRunner::GetCurrentDefault());
{
SingleThreadTaskRunner::CurrentDefaultHandle sttcd_override_2(
task_runner_2,
SingleThreadTaskRunner::CurrentDefaultHandle::MayAlreadyExist{});
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner_2, SingleThreadTaskRunner::GetCurrentDefault());
{
SingleThreadTaskRunner::CurrentDefaultHandle sttcd_override_3(
task_runner_3,
SingleThreadTaskRunner::CurrentDefaultHandle::MayAlreadyExist{});
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner_3, SingleThreadTaskRunner::GetCurrentDefault());
}
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner_2, SingleThreadTaskRunner::GetCurrentDefault());
{
SingleThreadTaskRunner::CurrentDefaultHandle sttcd_override_4(
task_runner_4,
SingleThreadTaskRunner::CurrentDefaultHandle::MayAlreadyExist{});
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner_4, SingleThreadTaskRunner::GetCurrentDefault());
}
}
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner_1, SingleThreadTaskRunner::GetCurrentDefault());
}
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
}
TEST(SingleThreadTaskRunnerCurrentDefaultHandleTest, OverrideWithNull) {
auto tr1 = MakeRefCounted<TestSimpleTaskRunner>();
SingleThreadTaskRunner::CurrentDefaultHandle handle(
tr1, SingleThreadTaskRunner::CurrentDefaultHandle::MayAlreadyExist{});
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(tr1, SingleThreadTaskRunner::GetCurrentDefault());
EXPECT_TRUE(SequencedTaskRunner::HasCurrentDefault());
EXPECT_EQ(tr1, SequencedTaskRunner::GetCurrentDefault());
{
SingleThreadTaskRunner::CurrentDefaultHandle nested_handle(
nullptr,
SingleThreadTaskRunner::CurrentDefaultHandle::MayAlreadyExist{});
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_CHECK_DEATH(
{ auto tr2 = SingleThreadTaskRunner::GetCurrentDefault(); });
EXPECT_FALSE(SequencedTaskRunner::HasCurrentDefault());
EXPECT_CHECK_DEATH(
{ auto tr2 = SequencedTaskRunner::GetCurrentDefault(); });
}
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(tr1, SingleThreadTaskRunner::GetCurrentDefault());
EXPECT_TRUE(SequencedTaskRunner::HasCurrentDefault());
EXPECT_EQ(tr1, SequencedTaskRunner::GetCurrentDefault());
}
TEST(SingleThreadTaskRunnerCurrentDefaultHandleTest, OverrideWithNonNull) {
auto tr1 = MakeRefCounted<TestSimpleTaskRunner>();
auto tr2 = MakeRefCounted<TestSimpleTaskRunner>();
SingleThreadTaskRunner::CurrentDefaultHandle handle(
tr1, SingleThreadTaskRunner::CurrentDefaultHandle::MayAlreadyExist{});
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(tr1, SingleThreadTaskRunner::GetCurrentDefault());
EXPECT_TRUE(SequencedTaskRunner::HasCurrentDefault());
EXPECT_EQ(tr1, SequencedTaskRunner::GetCurrentDefault());
{
SingleThreadTaskRunner::CurrentDefaultHandle nested_handle(
tr2, SingleThreadTaskRunner::CurrentDefaultHandle::MayAlreadyExist{});
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(tr2, SingleThreadTaskRunner::GetCurrentDefault());
EXPECT_TRUE(SequencedTaskRunner::HasCurrentDefault());
EXPECT_EQ(tr2, SequencedTaskRunner::GetCurrentDefault());
}
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(tr1, SingleThreadTaskRunner::GetCurrentDefault());
EXPECT_TRUE(SequencedTaskRunner::HasCurrentDefault());
EXPECT_EQ(tr1, SequencedTaskRunner::GetCurrentDefault());
}
TEST(SingleThreadTaskRunnerCurrentDefaultHandleTest, OverrideNoExistingSTTCD) {
scoped_refptr<SingleThreadTaskRunner> task_runner_1(
MakeRefCounted<TestSimpleTaskRunner>());
scoped_refptr<SingleThreadTaskRunner> task_runner_2(
MakeRefCounted<TestSimpleTaskRunner>());
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
{
SingleThreadTaskRunner::CurrentHandleOverrideForTesting sttcd_override_1(
task_runner_1);
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner_1, SingleThreadTaskRunner::GetCurrentDefault());
{
SingleThreadTaskRunner::CurrentHandleOverrideForTesting sttcd_override_2(
task_runner_2);
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner_2, SingleThreadTaskRunner::GetCurrentDefault());
}
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner_1, SingleThreadTaskRunner::GetCurrentDefault());
}
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
}
TEST(SingleThreadTaskRunnerCurrentDefaultHandleTest, DeathOnSTTCDOverOverride) {
scoped_refptr<SingleThreadTaskRunner> task_runner(
MakeRefCounted<TestSimpleTaskRunner>());
scoped_refptr<SingleThreadTaskRunner> overidding_task_runner(
MakeRefCounted<TestSimpleTaskRunner>());
SingleThreadTaskRunner::CurrentHandleOverrideForTesting sttcd_override(
task_runner);
EXPECT_CHECK_DEATH({
SingleThreadTaskRunner::CurrentDefaultHandle overriding_sttrcd(
overidding_task_runner);
});
}
TEST(SingleThreadTaskRunnerCurrentDefaultHandleTest,
NestedRunLoopAllowedUnderHandleOverride) {
test::SingleThreadTaskEnvironment task_environment;
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
scoped_refptr<SingleThreadTaskRunner> task_runner(
MakeRefCounted<TestSimpleTaskRunner>());
SingleThreadTaskRunner::CurrentDefaultHandle sttrcd_override(
task_runner,
SingleThreadTaskRunner::CurrentDefaultHandle::MayAlreadyExist{});
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner, SingleThreadTaskRunner::GetCurrentDefault());
EXPECT_EQ(task_runner, SequencedTaskRunner::GetCurrentDefault());
RunLoop().RunUntilIdle();
}
TEST(SingleThreadTaskRunnerCurrentDefaultHandleTest,
NestedRunLoopDisallowedUnderHandleOverrideForTesting) {
test::SingleThreadTaskEnvironment task_environment;
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
scoped_refptr<SingleThreadTaskRunner> task_runner(
MakeRefCounted<TestSimpleTaskRunner>());
SingleThreadTaskRunner::CurrentHandleOverrideForTesting sttcd_override(
task_runner);
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(task_runner, SingleThreadTaskRunner::GetCurrentDefault());
EXPECT_EQ(task_runner, SequencedTaskRunner::GetCurrentDefault());
EXPECT_DCHECK_DEATH({ RunLoop().RunUntilIdle(); });
}
TEST(SingleThreadTaskRunnerMainThreadDefaultHandleTest, Basic) {
EXPECT_CHECK_DEATH(std::ignore =
SingleThreadTaskRunner::GetMainThreadDefault());
{
scoped_refptr<SingleThreadTaskRunner> task_runner(
MakeRefCounted<TestSimpleTaskRunner>());
SingleThreadTaskRunner::MainThreadDefaultHandle main_thread_default_handle(
task_runner);
EXPECT_TRUE(SingleThreadTaskRunner::GetMainThreadDefault());
}
EXPECT_CHECK_DEATH(std::ignore =
SingleThreadTaskRunner::GetMainThreadDefault());
}
TEST(SingleThreadTaskRunnerCurrentBestEffortTest, SequenceManagerSingleQueue) {
test::TaskEnvironment task_env;
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentBestEffort());
EXPECT_FALSE(SingleThreadTaskRunner::HasMainThreadBestEffort());
ASSERT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
ASSERT_TRUE(SingleThreadTaskRunner::HasMainThreadDefault());
EXPECT_EQ(SingleThreadTaskRunner::GetMainThreadBestEffort(),
SingleThreadTaskRunner::GetCurrentBestEffort());
EXPECT_EQ(SingleThreadTaskRunner::GetCurrentBestEffort(),
SingleThreadTaskRunner::GetCurrentDefault());
EXPECT_EQ(SingleThreadTaskRunner::GetMainThreadBestEffort(),
SingleThreadTaskRunner::GetMainThreadDefault());
}
TEST(SingleThreadTaskRunnerCurrentBestEffortTest, SequenceManagerManyQueues) {
test::TaskEnvironmentWithMainThreadPriorities task_env;
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentBestEffort());
EXPECT_TRUE(SingleThreadTaskRunner::HasMainThreadBestEffort());
ASSERT_TRUE(SingleThreadTaskRunner::GetCurrentBestEffort());
ASSERT_TRUE(SingleThreadTaskRunner::GetMainThreadBestEffort());
EXPECT_EQ(SingleThreadTaskRunner::GetMainThreadBestEffort(),
SingleThreadTaskRunner::GetCurrentBestEffort());
EXPECT_NE(SingleThreadTaskRunner::GetCurrentBestEffort(),
SingleThreadTaskRunner::GetCurrentDefault());
EXPECT_NE(SingleThreadTaskRunner::GetMainThreadBestEffort(),
SingleThreadTaskRunner::GetMainThreadDefault());
ThreadCheckerImpl thread_checker;
RunLoop run_loop;
auto quit_closure = BarrierClosure(4, run_loop.QuitClosure());
SingleThreadTaskRunner::GetCurrentBestEffort()->PostTask(
FROM_HERE, BindLambdaForTesting([&] {
EXPECT_TRUE(thread_checker.CalledOnValidThread())
<< "GetCurrentBestEffort";
}).Then(quit_closure));
SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE, BindLambdaForTesting([&] {
EXPECT_TRUE(thread_checker.CalledOnValidThread())
<< "GetCurrentDefault";
}).Then(quit_closure));
SingleThreadTaskRunner::GetMainThreadBestEffort()->PostTask(
FROM_HERE, BindLambdaForTesting([&] {
EXPECT_TRUE(thread_checker.CalledOnValidThread())
<< "GetMainThreadBestEffort";
}).Then(quit_closure));
SingleThreadTaskRunner::GetMainThreadDefault()->PostTask(
FROM_HERE, BindLambdaForTesting([&] {
EXPECT_TRUE(thread_checker.CalledOnValidThread())
<< "GetMainThreadDefault";
}).Then(quit_closure));
run_loop.Run();
}
TEST(SingleThreadTaskRunnerCurrentBestEffortTest, ThreadPoolSingleThreadTask) {
test::TaskEnvironmentWithMainThreadPriorities task_env;
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentBestEffort());
auto task_env_best_effort_task_runner =
SingleThreadTaskRunner::GetCurrentBestEffort();
EXPECT_EQ(SingleThreadTaskRunner::GetMainThreadBestEffort(),
task_env_best_effort_task_runner);
ThreadCheckerImpl thread_checker;
constexpr auto kPriorities =
std::to_array({TaskPriority::USER_BLOCKING, TaskPriority::BEST_EFFORT});
for (auto priority : kPriorities) {
ThreadPool::CreateSingleThreadTaskRunner({priority})
->PostTask(
FROM_HERE,
BindLambdaForTesting([&] {
SCOPED_TRACE(priority);
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentBestEffort());
ASSERT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_EQ(SingleThreadTaskRunner::GetCurrentBestEffort(),
SingleThreadTaskRunner::GetCurrentDefault());
EXPECT_NE(SingleThreadTaskRunner::GetCurrentBestEffort(),
task_env_best_effort_task_runner);
EXPECT_FALSE(thread_checker.CalledOnValidThread());
EXPECT_TRUE(SingleThreadTaskRunner::HasMainThreadBestEffort());
EXPECT_EQ(SingleThreadTaskRunner::GetMainThreadBestEffort(),
task_env_best_effort_task_runner);
}).Then(task_env.QuitClosure()));
task_env.RunUntilQuit();
}
}
TEST(SingleThreadTaskRunnerCurrentBestEffortTest, ThreadPoolSequencedTask) {
test::TaskEnvironmentWithMainThreadPriorities task_env;
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentBestEffort());
auto task_env_best_effort_task_runner =
SingleThreadTaskRunner::GetCurrentBestEffort();
EXPECT_EQ(SingleThreadTaskRunner::GetMainThreadBestEffort(),
task_env_best_effort_task_runner);
constexpr auto kPriorities =
std::to_array({TaskPriority::USER_BLOCKING, TaskPriority::BEST_EFFORT});
for (auto priority : kPriorities) {
ThreadPool::CreateSequencedTaskRunner({priority})
->PostTask(
FROM_HERE,
BindLambdaForTesting([&] {
SCOPED_TRACE(priority);
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentBestEffort());
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_TRUE(SingleThreadTaskRunner::HasMainThreadBestEffort());
EXPECT_EQ(SingleThreadTaskRunner::GetMainThreadBestEffort(),
task_env_best_effort_task_runner);
}).Then(task_env.QuitClosure()));
task_env.RunUntilQuit();
}
}
TEST(SingleThreadTaskRunnerCurrentBestEffortTest, ThreadPoolUnsequencedTask) {
test::TaskEnvironmentWithMainThreadPriorities task_env;
EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentBestEffort());
auto task_env_best_effort_task_runner =
SingleThreadTaskRunner::GetCurrentBestEffort();
EXPECT_EQ(SingleThreadTaskRunner::GetMainThreadBestEffort(),
task_env_best_effort_task_runner);
constexpr auto kPriorities =
std::to_array({TaskPriority::USER_BLOCKING, TaskPriority::BEST_EFFORT});
for (auto priority : kPriorities) {
ThreadPool::PostTask(
FROM_HERE, {priority},
BindLambdaForTesting([&] {
SCOPED_TRACE(priority);
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentBestEffort());
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_TRUE(SingleThreadTaskRunner::HasMainThreadBestEffort());
EXPECT_EQ(SingleThreadTaskRunner::GetMainThreadBestEffort(),
task_env_best_effort_task_runner);
}).Then(task_env.QuitClosure()));
task_env.RunUntilQuit();
}
}
TEST(SingleTaskRunnerCurrentBestEffortDeathTest, NoContext) {
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentBestEffort());
EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
EXPECT_CHECK_DEATH(
{ auto task_runner = SingleThreadTaskRunner::GetCurrentBestEffort(); });
}
TEST(SingleTaskRunnerMainThreadBestEffortDeathTest, NoContext) {
EXPECT_FALSE(SingleThreadTaskRunner::HasMainThreadBestEffort());
EXPECT_FALSE(SingleThreadTaskRunner::HasMainThreadDefault());
EXPECT_CHECK_DEATH({
auto task_runner = SingleThreadTaskRunner::GetMainThreadBestEffort();
});
}
}