lazy_thread_pool_task_runner_unittest.cc 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/task/lazy_thread_pool_task_runner.h"
  5. #include "base/bind.h"
  6. #include "base/callback_helpers.h"
  7. #include "base/sequence_checker_impl.h"
  8. #include "base/task/scoped_set_task_priority_for_current_thread.h"
  9. #include "base/test/task_environment.h"
  10. #include "base/threading/thread_checker_impl.h"
  11. #include "build/build_config.h"
  12. #include "testing/gtest/include/gtest/gtest.h"
  13. #if BUILDFLAG(IS_WIN)
  14. #include "base/win/com_init_util.h"
  15. #endif
  16. namespace base {
  17. namespace {
  18. LazyThreadPoolSequencedTaskRunner g_sequenced_task_runner_user_visible =
  19. LAZY_THREAD_POOL_SEQUENCED_TASK_RUNNER_INITIALIZER(
  20. TaskTraits(TaskPriority::USER_VISIBLE));
  21. LazyThreadPoolSequencedTaskRunner g_sequenced_task_runner_user_blocking =
  22. LAZY_THREAD_POOL_SEQUENCED_TASK_RUNNER_INITIALIZER(
  23. TaskTraits(TaskPriority::USER_BLOCKING));
  24. LazyThreadPoolSingleThreadTaskRunner g_single_thread_task_runner_user_visible =
  25. LAZY_THREAD_POOL_SINGLE_THREAD_TASK_RUNNER_INITIALIZER(
  26. TaskTraits(TaskPriority::USER_VISIBLE),
  27. SingleThreadTaskRunnerThreadMode::SHARED);
  28. LazyThreadPoolSingleThreadTaskRunner g_single_thread_task_runner_user_blocking =
  29. LAZY_THREAD_POOL_SINGLE_THREAD_TASK_RUNNER_INITIALIZER(
  30. TaskTraits(TaskPriority::USER_BLOCKING),
  31. SingleThreadTaskRunnerThreadMode::SHARED);
  32. #if BUILDFLAG(IS_WIN)
  33. LazyThreadPoolCOMSTATaskRunner g_com_sta_task_runner_user_visible =
  34. LAZY_COM_STA_TASK_RUNNER_INITIALIZER(
  35. TaskTraits(TaskPriority::USER_VISIBLE),
  36. SingleThreadTaskRunnerThreadMode::SHARED);
  37. LazyThreadPoolCOMSTATaskRunner g_com_sta_task_runner_user_blocking =
  38. LAZY_COM_STA_TASK_RUNNER_INITIALIZER(
  39. TaskTraits(TaskPriority::USER_BLOCKING),
  40. SingleThreadTaskRunnerThreadMode::SHARED);
  41. #endif // BUILDFLAG(IS_WIN)
  42. void InitCheckers(SequenceCheckerImpl* sequence_checker,
  43. ThreadCheckerImpl* thread_checker) {
  44. sequence_checker->DetachFromSequence();
  45. EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
  46. thread_checker->DetachFromThread();
  47. EXPECT_TRUE(thread_checker->CalledOnValidThread());
  48. }
  49. void ExpectSequencedEnvironment(SequenceCheckerImpl* sequence_checker,
  50. ThreadCheckerImpl* thread_checker,
  51. TaskPriority expected_priority) {
  52. EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
  53. EXPECT_FALSE(thread_checker->CalledOnValidThread());
  54. EXPECT_EQ(expected_priority, internal::GetTaskPriorityForCurrentThread());
  55. }
  56. void ExpectSingleThreadEnvironment(SequenceCheckerImpl* sequence_checker,
  57. ThreadCheckerImpl* thread_checker,
  58. TaskPriority expected_priority
  59. #if BUILDFLAG(IS_WIN)
  60. ,
  61. bool expect_com_sta = false
  62. #endif
  63. ) {
  64. EXPECT_TRUE(sequence_checker->CalledOnValidSequence());
  65. EXPECT_TRUE(thread_checker->CalledOnValidThread());
  66. EXPECT_EQ(expected_priority, internal::GetTaskPriorityForCurrentThread());
  67. #if BUILDFLAG(IS_WIN)
  68. if (expect_com_sta)
  69. win::AssertComApartmentType(win::ComApartmentType::STA);
  70. #endif
  71. }
  72. class LazyThreadPoolTaskRunnerEnvironmentTest : public testing::Test {
  73. public:
  74. LazyThreadPoolTaskRunnerEnvironmentTest(
  75. const LazyThreadPoolTaskRunnerEnvironmentTest&) = delete;
  76. LazyThreadPoolTaskRunnerEnvironmentTest& operator=(
  77. const LazyThreadPoolTaskRunnerEnvironmentTest&) = delete;
  78. protected:
  79. LazyThreadPoolTaskRunnerEnvironmentTest() = default;
  80. void TestTaskRunnerEnvironment(scoped_refptr<SequencedTaskRunner> task_runner,
  81. bool expect_single_thread,
  82. TaskPriority expected_priority
  83. #if BUILDFLAG(IS_WIN)
  84. ,
  85. bool expect_com_sta = false
  86. #endif
  87. ) {
  88. SequenceCheckerImpl sequence_checker;
  89. ThreadCheckerImpl thread_checker;
  90. task_runner->PostTask(FROM_HERE,
  91. BindOnce(&InitCheckers, Unretained(&sequence_checker),
  92. Unretained(&thread_checker)));
  93. task_environment_.RunUntilIdle();
  94. OnceClosure task =
  95. expect_single_thread
  96. ? BindOnce(&ExpectSingleThreadEnvironment,
  97. Unretained(&sequence_checker),
  98. Unretained(&thread_checker), expected_priority
  99. #if BUILDFLAG(IS_WIN)
  100. ,
  101. expect_com_sta
  102. #endif
  103. )
  104. : BindOnce(&ExpectSequencedEnvironment,
  105. Unretained(&sequence_checker),
  106. Unretained(&thread_checker), expected_priority);
  107. task_runner->PostTask(FROM_HERE, std::move(task));
  108. task_environment_.RunUntilIdle();
  109. }
  110. test::TaskEnvironment task_environment_;
  111. };
  112. } // namespace
  113. TEST_F(LazyThreadPoolTaskRunnerEnvironmentTest,
  114. LazyThreadPoolSequencedTaskRunnerUserVisible) {
  115. TestTaskRunnerEnvironment(g_sequenced_task_runner_user_visible.Get(), false,
  116. TaskPriority::USER_VISIBLE);
  117. }
  118. TEST_F(LazyThreadPoolTaskRunnerEnvironmentTest,
  119. LazyThreadPoolSequencedTaskRunnerUserBlocking) {
  120. TestTaskRunnerEnvironment(g_sequenced_task_runner_user_blocking.Get(), false,
  121. TaskPriority::USER_BLOCKING);
  122. }
  123. TEST_F(LazyThreadPoolTaskRunnerEnvironmentTest,
  124. LazyThreadPoolSingleThreadTaskRunnerUserVisible) {
  125. TestTaskRunnerEnvironment(g_single_thread_task_runner_user_visible.Get(),
  126. true, TaskPriority::USER_VISIBLE);
  127. }
  128. TEST_F(LazyThreadPoolTaskRunnerEnvironmentTest,
  129. LazyThreadPoolSingleThreadTaskRunnerUserBlocking) {
  130. TestTaskRunnerEnvironment(g_single_thread_task_runner_user_blocking.Get(),
  131. true, TaskPriority::USER_BLOCKING);
  132. }
  133. #if BUILDFLAG(IS_WIN)
  134. TEST_F(LazyThreadPoolTaskRunnerEnvironmentTest,
  135. LazyThreadPoolCOMSTATaskRunnerUserVisible) {
  136. TestTaskRunnerEnvironment(g_com_sta_task_runner_user_visible.Get(), true,
  137. TaskPriority::USER_VISIBLE, true);
  138. }
  139. TEST_F(LazyThreadPoolTaskRunnerEnvironmentTest,
  140. LazyThreadPoolCOMSTATaskRunnerUserBlocking) {
  141. TestTaskRunnerEnvironment(g_com_sta_task_runner_user_blocking.Get(), true,
  142. TaskPriority::USER_BLOCKING, true);
  143. }
  144. #endif // BUILDFLAG(IS_WIN)
  145. TEST(LazyThreadPoolTaskRunnerTest, LazyThreadPoolSequencedTaskRunnerReset) {
  146. for (int i = 0; i < 2; ++i) {
  147. test::TaskEnvironment task_environment;
  148. // If the TaskRunner isn't released when the test::TaskEnvironment
  149. // goes out of scope, the second invocation of the line below will access a
  150. // deleted ThreadPoolInstance and crash.
  151. g_sequenced_task_runner_user_visible.Get()->PostTask(FROM_HERE,
  152. DoNothing());
  153. }
  154. }
  155. TEST(LazyThreadPoolTaskRunnerTest, LazyThreadPoolSingleThreadTaskRunnerReset) {
  156. for (int i = 0; i < 2; ++i) {
  157. test::TaskEnvironment task_environment;
  158. // If the TaskRunner isn't released when the test::TaskEnvironment
  159. // goes out of scope, the second invocation of the line below will access a
  160. // deleted ThreadPoolInstance and crash.
  161. g_single_thread_task_runner_user_visible.Get()->PostTask(FROM_HERE,
  162. DoNothing());
  163. }
  164. }
  165. #if BUILDFLAG(IS_WIN)
  166. TEST(LazyThreadPoolTaskRunnerTest, LazyThreadPoolCOMSTATaskRunnerReset) {
  167. for (int i = 0; i < 2; ++i) {
  168. test::TaskEnvironment task_environment;
  169. // If the TaskRunner isn't released when the test::TaskEnvironment
  170. // goes out of scope, the second invocation of the line below will access a
  171. // deleted ThreadPoolInstance and crash.
  172. g_com_sta_task_runner_user_visible.Get()->PostTask(FROM_HERE, DoNothing());
  173. }
  174. }
  175. #endif // BUILDFLAG(IS_WIN)
  176. } // namespace base