123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- // Copyright 2017 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "base/task/lazy_thread_pool_task_runner.h"
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/sequence_checker_impl.h"
- #include "base/task/scoped_set_task_priority_for_current_thread.h"
- #include "base/test/task_environment.h"
- #include "base/threading/thread_checker_impl.h"
- #include "build/build_config.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #if BUILDFLAG(IS_WIN)
- #include "base/win/com_init_util.h"
- #endif
- namespace base {
- namespace {
- LazyThreadPoolSequencedTaskRunner g_sequenced_task_runner_user_visible =
- LAZY_THREAD_POOL_SEQUENCED_TASK_RUNNER_INITIALIZER(
- TaskTraits(TaskPriority::USER_VISIBLE));
- LazyThreadPoolSequencedTaskRunner g_sequenced_task_runner_user_blocking =
- LAZY_THREAD_POOL_SEQUENCED_TASK_RUNNER_INITIALIZER(
- TaskTraits(TaskPriority::USER_BLOCKING));
- LazyThreadPoolSingleThreadTaskRunner g_single_thread_task_runner_user_visible =
- LAZY_THREAD_POOL_SINGLE_THREAD_TASK_RUNNER_INITIALIZER(
- TaskTraits(TaskPriority::USER_VISIBLE),
- SingleThreadTaskRunnerThreadMode::SHARED);
- LazyThreadPoolSingleThreadTaskRunner g_single_thread_task_runner_user_blocking =
- LAZY_THREAD_POOL_SINGLE_THREAD_TASK_RUNNER_INITIALIZER(
- TaskTraits(TaskPriority::USER_BLOCKING),
- SingleThreadTaskRunnerThreadMode::SHARED);
- #if BUILDFLAG(IS_WIN)
- LazyThreadPoolCOMSTATaskRunner g_com_sta_task_runner_user_visible =
- LAZY_COM_STA_TASK_RUNNER_INITIALIZER(
- TaskTraits(TaskPriority::USER_VISIBLE),
- SingleThreadTaskRunnerThreadMode::SHARED);
- LazyThreadPoolCOMSTATaskRunner g_com_sta_task_runner_user_blocking =
- LAZY_COM_STA_TASK_RUNNER_INITIALIZER(
- TaskTraits(TaskPriority::USER_BLOCKING),
- SingleThreadTaskRunnerThreadMode::SHARED);
- #endif // BUILDFLAG(IS_WIN)
- void InitCheckers(SequenceCheckerImpl* sequence_checker,
- ThreadCheckerImpl* thread_checker) {
- sequence_checker->DetachFromSequence();
- EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
- thread_checker->DetachFromThread();
- EXPECT_TRUE(thread_checker->CalledOnValidThread());
- }
- void ExpectSequencedEnvironment(SequenceCheckerImpl* sequence_checker,
- ThreadCheckerImpl* thread_checker,
- TaskPriority expected_priority) {
- EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
- EXPECT_FALSE(thread_checker->CalledOnValidThread());
- EXPECT_EQ(expected_priority, internal::GetTaskPriorityForCurrentThread());
- }
- void ExpectSingleThreadEnvironment(SequenceCheckerImpl* sequence_checker,
- ThreadCheckerImpl* thread_checker,
- TaskPriority expected_priority
- #if BUILDFLAG(IS_WIN)
- ,
- bool expect_com_sta = false
- #endif
- ) {
- EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
- EXPECT_TRUE(thread_checker->CalledOnValidThread());
- EXPECT_EQ(expected_priority, internal::GetTaskPriorityForCurrentThread());
- #if BUILDFLAG(IS_WIN)
- if (expect_com_sta)
- win::AssertComApartmentType(win::ComApartmentType::STA);
- #endif
- }
- class LazyThreadPoolTaskRunnerEnvironmentTest : public testing::Test {
- public:
- LazyThreadPoolTaskRunnerEnvironmentTest(
- const LazyThreadPoolTaskRunnerEnvironmentTest&) = delete;
- LazyThreadPoolTaskRunnerEnvironmentTest& operator=(
- const LazyThreadPoolTaskRunnerEnvironmentTest&) = delete;
- protected:
- LazyThreadPoolTaskRunnerEnvironmentTest() = default;
- void TestTaskRunnerEnvironment(scoped_refptr<SequencedTaskRunner> task_runner,
- bool expect_single_thread,
- TaskPriority expected_priority
- #if BUILDFLAG(IS_WIN)
- ,
- bool expect_com_sta = false
- #endif
- ) {
- SequenceCheckerImpl sequence_checker;
- ThreadCheckerImpl thread_checker;
- task_runner->PostTask(FROM_HERE,
- BindOnce(&InitCheckers, Unretained(&sequence_checker),
- Unretained(&thread_checker)));
- task_environment_.RunUntilIdle();
- OnceClosure task =
- expect_single_thread
- ? BindOnce(&ExpectSingleThreadEnvironment,
- Unretained(&sequence_checker),
- Unretained(&thread_checker), expected_priority
- #if BUILDFLAG(IS_WIN)
- ,
- expect_com_sta
- #endif
- )
- : BindOnce(&ExpectSequencedEnvironment,
- Unretained(&sequence_checker),
- Unretained(&thread_checker), expected_priority);
- task_runner->PostTask(FROM_HERE, std::move(task));
- task_environment_.RunUntilIdle();
- }
- test::TaskEnvironment task_environment_;
- };
- } // namespace
- TEST_F(LazyThreadPoolTaskRunnerEnvironmentTest,
- LazyThreadPoolSequencedTaskRunnerUserVisible) {
- TestTaskRunnerEnvironment(g_sequenced_task_runner_user_visible.Get(), false,
- TaskPriority::USER_VISIBLE);
- }
- TEST_F(LazyThreadPoolTaskRunnerEnvironmentTest,
- LazyThreadPoolSequencedTaskRunnerUserBlocking) {
- TestTaskRunnerEnvironment(g_sequenced_task_runner_user_blocking.Get(), false,
- TaskPriority::USER_BLOCKING);
- }
- TEST_F(LazyThreadPoolTaskRunnerEnvironmentTest,
- LazyThreadPoolSingleThreadTaskRunnerUserVisible) {
- TestTaskRunnerEnvironment(g_single_thread_task_runner_user_visible.Get(),
- true, TaskPriority::USER_VISIBLE);
- }
- TEST_F(LazyThreadPoolTaskRunnerEnvironmentTest,
- LazyThreadPoolSingleThreadTaskRunnerUserBlocking) {
- TestTaskRunnerEnvironment(g_single_thread_task_runner_user_blocking.Get(),
- true, TaskPriority::USER_BLOCKING);
- }
- #if BUILDFLAG(IS_WIN)
- TEST_F(LazyThreadPoolTaskRunnerEnvironmentTest,
- LazyThreadPoolCOMSTATaskRunnerUserVisible) {
- TestTaskRunnerEnvironment(g_com_sta_task_runner_user_visible.Get(), true,
- TaskPriority::USER_VISIBLE, true);
- }
- TEST_F(LazyThreadPoolTaskRunnerEnvironmentTest,
- LazyThreadPoolCOMSTATaskRunnerUserBlocking) {
- TestTaskRunnerEnvironment(g_com_sta_task_runner_user_blocking.Get(), true,
- TaskPriority::USER_BLOCKING, true);
- }
- #endif // BUILDFLAG(IS_WIN)
- TEST(LazyThreadPoolTaskRunnerTest, LazyThreadPoolSequencedTaskRunnerReset) {
- for (int i = 0; i < 2; ++i) {
- test::TaskEnvironment task_environment;
- // If the TaskRunner isn't released when the test::TaskEnvironment
- // goes out of scope, the second invocation of the line below will access a
- // deleted ThreadPoolInstance and crash.
- g_sequenced_task_runner_user_visible.Get()->PostTask(FROM_HERE,
- DoNothing());
- }
- }
- TEST(LazyThreadPoolTaskRunnerTest, LazyThreadPoolSingleThreadTaskRunnerReset) {
- for (int i = 0; i < 2; ++i) {
- test::TaskEnvironment task_environment;
- // If the TaskRunner isn't released when the test::TaskEnvironment
- // goes out of scope, the second invocation of the line below will access a
- // deleted ThreadPoolInstance and crash.
- g_single_thread_task_runner_user_visible.Get()->PostTask(FROM_HERE,
- DoNothing());
- }
- }
- #if BUILDFLAG(IS_WIN)
- TEST(LazyThreadPoolTaskRunnerTest, LazyThreadPoolCOMSTATaskRunnerReset) {
- for (int i = 0; i < 2; ++i) {
- test::TaskEnvironment task_environment;
- // If the TaskRunner isn't released when the test::TaskEnvironment
- // goes out of scope, the second invocation of the line below will access a
- // deleted ThreadPoolInstance and crash.
- g_com_sta_task_runner_user_visible.Get()->PostTask(FROM_HERE, DoNothing());
- }
- }
- #endif // BUILDFLAG(IS_WIN)
- } // namespace base
|