| OLD | NEW | 
|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "base/task_scheduler/scheduler_single_thread_task_runner_manager.h" | 5 #include "base/task_scheduler/scheduler_single_thread_task_runner_manager.h" | 
| 6 | 6 | 
| 7 #include "base/bind.h" | 7 #include "base/bind.h" | 
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" | 
| 9 #include "base/synchronization/atomic_flag.h" | 9 #include "base/synchronization/atomic_flag.h" | 
| 10 #include "base/synchronization/lock.h" | 10 #include "base/synchronization/lock.h" | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 25 #include <objbase.h> | 25 #include <objbase.h> | 
| 26 | 26 | 
| 27 #include "base/win/current_module.h" | 27 #include "base/win/current_module.h" | 
| 28 #endif  // defined(OS_WIN) | 28 #endif  // defined(OS_WIN) | 
| 29 | 29 | 
| 30 namespace base { | 30 namespace base { | 
| 31 namespace internal { | 31 namespace internal { | 
| 32 | 32 | 
| 33 namespace { | 33 namespace { | 
| 34 | 34 | 
| 35 enum WorkerPoolType : size_t { |  | 
| 36   BACKGROUND_WORKER_POOL = 0, |  | 
| 37   FOREGROUND_WORKER_POOL, |  | 
| 38 }; |  | 
| 39 |  | 
| 40 static size_t GetThreadPoolIndexForTraits(const TaskTraits& traits) { |  | 
| 41   return traits.priority() == TaskPriority::BACKGROUND ? BACKGROUND_WORKER_POOL |  | 
| 42                                                        : FOREGROUND_WORKER_POOL; |  | 
| 43 } |  | 
| 44 |  | 
| 45 std::vector<SchedulerWorkerPoolParams> GetParamsVector() { |  | 
| 46   using StandbyThreadPolicy = SchedulerWorkerPoolParams::StandbyThreadPolicy; |  | 
| 47 |  | 
| 48   std::vector<SchedulerWorkerPoolParams> params_vector; |  | 
| 49 |  | 
| 50   DCHECK_EQ(BACKGROUND_WORKER_POOL, params_vector.size()); |  | 
| 51   params_vector.emplace_back("Background", ThreadPriority::BACKGROUND, |  | 
| 52                              StandbyThreadPolicy::LAZY, 1U, TimeDelta::Max()); |  | 
| 53 |  | 
| 54   DCHECK_EQ(FOREGROUND_WORKER_POOL, params_vector.size()); |  | 
| 55   params_vector.emplace_back("Foreground", ThreadPriority::NORMAL, |  | 
| 56                              StandbyThreadPolicy::LAZY, 1U, TimeDelta::Max()); |  | 
| 57 |  | 
| 58   return params_vector; |  | 
| 59 } |  | 
| 60 |  | 
| 61 class TaskSchedulerSingleThreadTaskRunnerManagerTest : public testing::Test { | 35 class TaskSchedulerSingleThreadTaskRunnerManagerTest : public testing::Test { | 
| 62  public: | 36  public: | 
| 63   TaskSchedulerSingleThreadTaskRunnerManagerTest() | 37   TaskSchedulerSingleThreadTaskRunnerManagerTest() | 
| 64       : service_thread_("TaskSchedulerServiceThread") {} | 38       : service_thread_("TaskSchedulerServiceThread") {} | 
| 65 | 39 | 
| 66   void SetUp() override { | 40   void SetUp() override { | 
| 67     service_thread_.Start(); | 41     service_thread_.Start(); | 
| 68 |  | 
| 69     delayed_task_manager_ = | 42     delayed_task_manager_ = | 
| 70         MakeUnique<DelayedTaskManager>(service_thread_.task_runner()); | 43         MakeUnique<DelayedTaskManager>(service_thread_.task_runner()); | 
| 71     single_thread_task_runner_manager_ = | 44     single_thread_task_runner_manager_ = | 
| 72         MakeUnique<SchedulerSingleThreadTaskRunnerManager>( | 45         MakeUnique<SchedulerSingleThreadTaskRunnerManager>( | 
| 73             GetParamsVector(), Bind(&GetThreadPoolIndexForTraits), |  | 
| 74             &task_tracker_, delayed_task_manager_.get()); | 46             &task_tracker_, delayed_task_manager_.get()); | 
| 75     StartSingleThreadTaskRunnerManagerFromSetUp(); | 47     StartSingleThreadTaskRunnerManagerFromSetUp(); | 
| 76   } | 48   } | 
| 77 | 49 | 
| 78   void TearDown() override { | 50   void TearDown() override { | 
| 79     TearDownSingleThreadTaskRunnerManager(); | 51     TearDownSingleThreadTaskRunnerManager(); | 
| 80     delayed_task_manager_.reset(); | 52     delayed_task_manager_.reset(); | 
| 81     service_thread_.Stop(); | 53     service_thread_.Stop(); | 
| 82   } | 54   } | 
| 83 | 55 | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 115 void ShouldNotRun() { | 87 void ShouldNotRun() { | 
| 116   ADD_FAILURE() << "Ran a task that shouldn't run."; | 88   ADD_FAILURE() << "Ran a task that shouldn't run."; | 
| 117 } | 89 } | 
| 118 | 90 | 
| 119 }  // namespace | 91 }  // namespace | 
| 120 | 92 | 
| 121 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) { | 93 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) { | 
| 122   scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 94   scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 
| 123       single_thread_task_runner_manager_ | 95       single_thread_task_runner_manager_ | 
| 124           ->CreateSingleThreadTaskRunnerWithTraits( | 96           ->CreateSingleThreadTaskRunnerWithTraits( | 
|  | 97               "A", ThreadPriority::NORMAL, | 
| 125               TaskTraits().WithShutdownBehavior( | 98               TaskTraits().WithShutdownBehavior( | 
| 126                   TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 99                   TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 
| 127   scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 100   scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 
| 128       single_thread_task_runner_manager_ | 101       single_thread_task_runner_manager_ | 
| 129           ->CreateSingleThreadTaskRunnerWithTraits( | 102           ->CreateSingleThreadTaskRunnerWithTraits( | 
|  | 103               "B", ThreadPriority::NORMAL, | 
| 130               TaskTraits().WithShutdownBehavior( | 104               TaskTraits().WithShutdownBehavior( | 
| 131                   TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 105                   TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 
| 132 | 106 | 
| 133   PlatformThreadRef thread_ref_1; | 107   PlatformThreadRef thread_ref_1; | 
| 134   task_runner_1->PostTask(FROM_HERE, | 108   task_runner_1->PostTask(FROM_HERE, | 
| 135                           BindOnce(&CaptureThreadRef, &thread_ref_1)); | 109                           BindOnce(&CaptureThreadRef, &thread_ref_1)); | 
| 136   PlatformThreadRef thread_ref_2; | 110   PlatformThreadRef thread_ref_2; | 
| 137   task_runner_2->PostTask(FROM_HERE, | 111   task_runner_2->PostTask(FROM_HERE, | 
| 138                           BindOnce(&CaptureThreadRef, &thread_ref_2)); | 112                           BindOnce(&CaptureThreadRef, &thread_ref_2)); | 
| 139 | 113 | 
| 140   task_tracker_.Shutdown(); | 114   task_tracker_.Shutdown(); | 
| 141 | 115 | 
| 142   ASSERT_FALSE(thread_ref_1.is_null()); | 116   ASSERT_FALSE(thread_ref_1.is_null()); | 
| 143   ASSERT_FALSE(thread_ref_2.is_null()); | 117   ASSERT_FALSE(thread_ref_2.is_null()); | 
| 144   EXPECT_NE(thread_ref_1, thread_ref_2); | 118   EXPECT_NE(thread_ref_1, thread_ref_2); | 
| 145 } | 119 } | 
| 146 | 120 | 
| 147 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { | 121 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { | 
| 148   // Why are events used here instead of the task tracker? | 122   // Why are events used here instead of the task tracker? | 
| 149   // Shutting down can cause priorities to get raised. This means we have to use | 123   // Shutting down can cause priorities to get raised. This means we have to use | 
| 150   // events to determine when a task is run. | 124   // events to determine when a task is run. | 
| 151   scoped_refptr<SingleThreadTaskRunner> task_runner_background = | 125   scoped_refptr<SingleThreadTaskRunner> task_runner_background = | 
| 152       single_thread_task_runner_manager_ | 126       single_thread_task_runner_manager_ | 
| 153           ->CreateSingleThreadTaskRunnerWithTraits( | 127           ->CreateSingleThreadTaskRunnerWithTraits( | 
|  | 128               "Background", ThreadPriority::BACKGROUND, | 
| 154               TaskTraits().WithPriority(TaskPriority::BACKGROUND)); | 129               TaskTraits().WithPriority(TaskPriority::BACKGROUND)); | 
| 155   scoped_refptr<SingleThreadTaskRunner> task_runner_user_visible = | 130   scoped_refptr<SingleThreadTaskRunner> task_runner_normal = | 
| 156       single_thread_task_runner_manager_ | 131       single_thread_task_runner_manager_ | 
| 157           ->CreateSingleThreadTaskRunnerWithTraits( | 132           ->CreateSingleThreadTaskRunnerWithTraits( | 
|  | 133               "Normal", ThreadPriority::NORMAL, | 
| 158               TaskTraits().WithPriority(TaskPriority::USER_VISIBLE)); | 134               TaskTraits().WithPriority(TaskPriority::USER_VISIBLE)); | 
| 159   scoped_refptr<SingleThreadTaskRunner> task_runner_user_blocking = |  | 
| 160       single_thread_task_runner_manager_ |  | 
| 161           ->CreateSingleThreadTaskRunnerWithTraits( |  | 
| 162               TaskTraits() |  | 
| 163                   .WithPriority(TaskPriority::USER_BLOCKING) |  | 
| 164                   .WithShutdownBehavior(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |  | 
| 165 | 135 | 
| 166   ThreadPriority thread_priority_background; | 136   ThreadPriority thread_priority_background; | 
| 167   task_runner_background->PostTask( | 137   task_runner_background->PostTask( | 
| 168       FROM_HERE, BindOnce(&CaptureThreadPriority, &thread_priority_background)); | 138       FROM_HERE, BindOnce(&CaptureThreadPriority, &thread_priority_background)); | 
| 169   WaitableEvent waitable_event_background( | 139   WaitableEvent waitable_event_background( | 
| 170       WaitableEvent::ResetPolicy::MANUAL, | 140       WaitableEvent::ResetPolicy::MANUAL, | 
| 171       WaitableEvent::InitialState::NOT_SIGNALED); | 141       WaitableEvent::InitialState::NOT_SIGNALED); | 
| 172   task_runner_background->PostTask( | 142   task_runner_background->PostTask( | 
| 173       FROM_HERE, | 143       FROM_HERE, | 
| 174       BindOnce(&WaitableEvent::Signal, Unretained(&waitable_event_background))); | 144       BindOnce(&WaitableEvent::Signal, Unretained(&waitable_event_background))); | 
| 175 | 145 | 
| 176   ThreadPriority thread_priority_user_visible; | 146   ThreadPriority thread_priority_normal; | 
| 177   task_runner_user_visible->PostTask( | 147   task_runner_normal->PostTask( | 
| 178       FROM_HERE, | 148       FROM_HERE, BindOnce(&CaptureThreadPriority, &thread_priority_normal)); | 
| 179       BindOnce(&CaptureThreadPriority, &thread_priority_user_visible)); | 149   WaitableEvent waitable_event_normal( | 
| 180   WaitableEvent waitable_event_user_visible( |  | 
| 181       WaitableEvent::ResetPolicy::MANUAL, | 150       WaitableEvent::ResetPolicy::MANUAL, | 
| 182       WaitableEvent::InitialState::NOT_SIGNALED); | 151       WaitableEvent::InitialState::NOT_SIGNALED); | 
| 183   task_runner_user_visible->PostTask( | 152   task_runner_normal->PostTask( | 
| 184       FROM_HERE, BindOnce(&WaitableEvent::Signal, |  | 
| 185                           Unretained(&waitable_event_user_visible))); |  | 
| 186 |  | 
| 187   ThreadPriority thread_priority_user_blocking; |  | 
| 188   task_runner_user_blocking->PostTask( |  | 
| 189       FROM_HERE, | 153       FROM_HERE, | 
| 190       BindOnce(&CaptureThreadPriority, &thread_priority_user_blocking)); | 154       BindOnce(&WaitableEvent::Signal, Unretained(&waitable_event_normal))); | 
| 191   WaitableEvent waitable_event_user_blocking( |  | 
| 192       WaitableEvent::ResetPolicy::MANUAL, |  | 
| 193       WaitableEvent::InitialState::NOT_SIGNALED); |  | 
| 194   task_runner_user_blocking->PostTask( |  | 
| 195       FROM_HERE, BindOnce(&WaitableEvent::Signal, |  | 
| 196                           Unretained(&waitable_event_user_blocking))); |  | 
| 197 | 155 | 
| 198   waitable_event_background.Wait(); | 156   waitable_event_background.Wait(); | 
| 199   waitable_event_user_visible.Wait(); | 157   waitable_event_normal.Wait(); | 
| 200   waitable_event_user_blocking.Wait(); |  | 
| 201 | 158 | 
| 202   if (Lock::HandlesMultipleThreadPriorities()) | 159   if (Lock::HandlesMultipleThreadPriorities()) | 
| 203     EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background); | 160     EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background); | 
| 204   else | 161   else | 
| 205     EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background); | 162     EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background); | 
| 206   EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_visible); | 163   EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_normal); | 
| 207   EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_blocking); |  | 
| 208 } | 164 } | 
| 209 | 165 | 
| 210 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskAfterShutdown) { | 166 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskAfterShutdown) { | 
| 211   auto task_runner = single_thread_task_runner_manager_ | 167   auto task_runner = single_thread_task_runner_manager_ | 
| 212                          ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); | 168                          ->CreateSingleThreadTaskRunnerWithTraits( | 
|  | 169                              "A", ThreadPriority::NORMAL, TaskTraits()); | 
| 213   task_tracker_.Shutdown(); | 170   task_tracker_.Shutdown(); | 
| 214   EXPECT_FALSE(task_runner->PostTask(FROM_HERE, BindOnce(&ShouldNotRun))); | 171   EXPECT_FALSE(task_runner->PostTask(FROM_HERE, BindOnce(&ShouldNotRun))); | 
| 215 } | 172 } | 
| 216 | 173 | 
| 217 // Verify that a Task runs shortly after its delay expires. | 174 // Verify that a Task runs shortly after its delay expires. | 
| 218 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostDelayedTask) { | 175 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostDelayedTask) { | 
| 219   TimeTicks start_time = TimeTicks::Now(); | 176   TimeTicks start_time = TimeTicks::Now(); | 
| 220 | 177 | 
| 221   // Post a task with a short delay. | 178   // Post a task with a short delay. | 
| 222   WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 179   WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 
| 223                          WaitableEvent::InitialState::NOT_SIGNALED); | 180                          WaitableEvent::InitialState::NOT_SIGNALED); | 
| 224   auto task_runner = single_thread_task_runner_manager_ | 181   auto task_runner = single_thread_task_runner_manager_ | 
| 225                          ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); | 182                          ->CreateSingleThreadTaskRunnerWithTraits( | 
|  | 183                              "A", ThreadPriority::NORMAL, TaskTraits()); | 
| 226   EXPECT_TRUE(task_runner->PostDelayedTask( | 184   EXPECT_TRUE(task_runner->PostDelayedTask( | 
| 227       FROM_HERE, BindOnce(&WaitableEvent::Signal, Unretained(&task_ran)), | 185       FROM_HERE, BindOnce(&WaitableEvent::Signal, Unretained(&task_ran)), | 
| 228       TestTimeouts::tiny_timeout())); | 186       TestTimeouts::tiny_timeout())); | 
| 229 | 187 | 
| 230   // Wait until the task runs. | 188   // Wait until the task runs. | 
| 231   task_ran.Wait(); | 189   task_ran.Wait(); | 
| 232 | 190 | 
| 233   // Expect the task to run after its delay expires, but not more than 250 ms | 191   // Expect the task to run after its delay expires, but not more than 250 ms | 
| 234   // after that. | 192   // after that. | 
| 235   const TimeDelta actual_delay = TimeTicks::Now() - start_time; | 193   const TimeDelta actual_delay = TimeTicks::Now() - start_time; | 
| 236   EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); | 194   EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); | 
| 237   EXPECT_LT(actual_delay, | 195   EXPECT_LT(actual_delay, | 
| 238             TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); | 196             TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); | 
| 239 } | 197 } | 
| 240 | 198 | 
| 241 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, | 199 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, | 
| 242        RunsTasksOnCurrentThread) { | 200        RunsTasksOnCurrentThread) { | 
| 243   scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 201   scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 
| 244       single_thread_task_runner_manager_ | 202       single_thread_task_runner_manager_ | 
| 245           ->CreateSingleThreadTaskRunnerWithTraits( | 203           ->CreateSingleThreadTaskRunnerWithTraits( | 
|  | 204               "A", ThreadPriority::NORMAL, | 
| 246               TaskTraits().WithShutdownBehavior( | 205               TaskTraits().WithShutdownBehavior( | 
| 247                   TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 206                   TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 
| 248   scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 207   scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 
| 249       single_thread_task_runner_manager_ | 208       single_thread_task_runner_manager_ | 
| 250           ->CreateSingleThreadTaskRunnerWithTraits( | 209           ->CreateSingleThreadTaskRunnerWithTraits( | 
|  | 210               "B", ThreadPriority::NORMAL, | 
| 251               TaskTraits().WithShutdownBehavior( | 211               TaskTraits().WithShutdownBehavior( | 
| 252                   TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 212                   TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 
| 253 | 213 | 
| 254   EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); | 214   EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); | 
| 255   EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); | 215   EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); | 
| 256 | 216 | 
| 257   task_runner_1->PostTask( | 217   task_runner_1->PostTask( | 
| 258       FROM_HERE, BindOnce( | 218       FROM_HERE, BindOnce( | 
| 259                      [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, | 219                      [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, | 
| 260                         scoped_refptr<SingleThreadTaskRunner> task_runner_2) { | 220                         scoped_refptr<SingleThreadTaskRunner> task_runner_2) { | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 324   // Exercises the codepath where the workers are unavailable for unregistration | 284   // Exercises the codepath where the workers are unavailable for unregistration | 
| 325   // because of a Join call. | 285   // because of a Join call. | 
| 326   WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 286   WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 
| 327                              WaitableEvent::InitialState::NOT_SIGNALED); | 287                              WaitableEvent::InitialState::NOT_SIGNALED); | 
| 328   WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 288   WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 
| 329                               WaitableEvent::InitialState::NOT_SIGNALED); | 289                               WaitableEvent::InitialState::NOT_SIGNALED); | 
| 330 | 290 | 
| 331   { | 291   { | 
| 332     auto task_runner = single_thread_task_runner_manager_ | 292     auto task_runner = single_thread_task_runner_manager_ | 
| 333                            ->CreateSingleThreadTaskRunnerWithTraits( | 293                            ->CreateSingleThreadTaskRunnerWithTraits( | 
|  | 294                                "A", ThreadPriority::NORMAL, | 
| 334                                TaskTraits().WithBaseSyncPrimitives()); | 295                                TaskTraits().WithBaseSyncPrimitives()); | 
| 335     EXPECT_TRUE(task_runner->PostTask( | 296     EXPECT_TRUE(task_runner->PostTask( | 
| 336         FROM_HERE, | 297         FROM_HERE, | 
| 337         BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); | 298         BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); | 
| 338     EXPECT_TRUE(task_runner->PostTask( | 299     EXPECT_TRUE(task_runner->PostTask( | 
| 339         FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 300         FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 
| 340   } | 301   } | 
| 341 | 302 | 
| 342   task_running.Wait(); | 303   task_running.Wait(); | 
| 343   CallJoinFromDifferentThread join_from_different_thread( | 304   CallJoinFromDifferentThread join_from_different_thread( | 
| 344       single_thread_task_runner_manager_.get()); | 305       single_thread_task_runner_manager_.get()); | 
| 345   join_from_different_thread.Start(); | 306   join_from_different_thread.Start(); | 
| 346   join_from_different_thread.WaitForRunToStart(); | 307   join_from_different_thread.WaitForRunToStart(); | 
| 347   task_blocking.Signal(); | 308   task_blocking.Signal(); | 
| 348   join_from_different_thread.Join(); | 309   join_from_different_thread.Join(); | 
| 349 } | 310 } | 
| 350 | 311 | 
| 351 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, | 312 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, | 
| 352        ConcurrentJoinExtraSkippedTask) { | 313        ConcurrentJoinExtraSkippedTask) { | 
| 353   // Tests to make sure that tasks are properly cleaned up at Join, allowing | 314   // Tests to make sure that tasks are properly cleaned up at Join, allowing | 
| 354   // SingleThreadTaskRunners to unregister themselves. | 315   // SingleThreadTaskRunners to unregister themselves. | 
| 355   WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 316   WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 
| 356                              WaitableEvent::InitialState::NOT_SIGNALED); | 317                              WaitableEvent::InitialState::NOT_SIGNALED); | 
| 357   WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 318   WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 
| 358                               WaitableEvent::InitialState::NOT_SIGNALED); | 319                               WaitableEvent::InitialState::NOT_SIGNALED); | 
| 359 | 320 | 
| 360   { | 321   { | 
| 361     auto task_runner = single_thread_task_runner_manager_ | 322     auto task_runner = single_thread_task_runner_manager_ | 
| 362                            ->CreateSingleThreadTaskRunnerWithTraits( | 323                            ->CreateSingleThreadTaskRunnerWithTraits( | 
|  | 324                                "A", ThreadPriority::NORMAL, | 
| 363                                TaskTraits().WithBaseSyncPrimitives()); | 325                                TaskTraits().WithBaseSyncPrimitives()); | 
| 364     EXPECT_TRUE(task_runner->PostTask( | 326     EXPECT_TRUE(task_runner->PostTask( | 
| 365         FROM_HERE, | 327         FROM_HERE, | 
| 366         BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); | 328         BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); | 
| 367     EXPECT_TRUE(task_runner->PostTask( | 329     EXPECT_TRUE(task_runner->PostTask( | 
| 368         FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 330         FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 
| 369     EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing))); | 331     EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing))); | 
| 370   } | 332   } | 
| 371 | 333 | 
| 372   task_running.Wait(); | 334   task_running.Wait(); | 
| 373   CallJoinFromDifferentThread join_from_different_thread( | 335   CallJoinFromDifferentThread join_from_different_thread( | 
| 374       single_thread_task_runner_manager_.get()); | 336       single_thread_task_runner_manager_.get()); | 
| 375   join_from_different_thread.Start(); | 337   join_from_different_thread.Start(); | 
| 376   join_from_different_thread.WaitForRunToStart(); | 338   join_from_different_thread.WaitForRunToStart(); | 
| 377   task_blocking.Signal(); | 339   task_blocking.Signal(); | 
| 378   join_from_different_thread.Join(); | 340   join_from_different_thread.Join(); | 
| 379 } | 341 } | 
| 380 | 342 | 
| 381 #if defined(OS_WIN) | 343 #if defined(OS_WIN) | 
| 382 | 344 | 
| 383 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTAInitialized) { | 345 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTAInitialized) { | 
| 384   scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 346   scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 
| 385       single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 347       single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 
|  | 348           "A", ThreadPriority::NORMAL, | 
| 386           TaskTraits().WithShutdownBehavior( | 349           TaskTraits().WithShutdownBehavior( | 
| 387               TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 350               TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 
| 388 | 351 | 
| 389   com_task_runner->PostTask( | 352   com_task_runner->PostTask( | 
| 390       FROM_HERE, Bind([]() { | 353       FROM_HERE, BindOnce([]() { | 
| 391         HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); | 354         HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); | 
| 392         if (SUCCEEDED(hr)) { | 355         if (SUCCEEDED(hr)) { | 
| 393           ADD_FAILURE() << "COM STA was not initialized on this thread"; | 356           ADD_FAILURE() << "COM STA was not initialized on this thread"; | 
| 394           CoUninitialize(); | 357           CoUninitialize(); | 
| 395         } | 358         } | 
| 396       })); | 359       })); | 
| 397 | 360 | 
| 398   task_tracker_.Shutdown(); | 361   task_tracker_.Shutdown(); | 
| 399 } | 362 } | 
| 400 | 363 | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 439   bool register_class_succeeded_ = false; | 402   bool register_class_succeeded_ = false; | 
| 440 | 403 | 
| 441   DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin); | 404   DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin); | 
| 442 }; | 405 }; | 
| 443 | 406 | 
| 444 }  // namespace | 407 }  // namespace | 
| 445 | 408 | 
| 446 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) { | 409 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) { | 
| 447   scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 410   scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 
| 448       single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 411       single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 
|  | 412           "A", ThreadPriority::NORMAL, | 
| 449           TaskTraits().WithShutdownBehavior( | 413           TaskTraits().WithShutdownBehavior( | 
| 450               TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 414               TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 
| 451   HWND hwnd = nullptr; | 415   HWND hwnd = nullptr; | 
| 452   // HWNDs process messages on the thread that created them, so we have to | 416   // HWNDs process messages on the thread that created them, so we have to | 
| 453   // create them within the context of the task runner to properly simulate a | 417   // create them within the context of the task runner to properly simulate a | 
| 454   // COM callback. | 418   // COM callback. | 
| 455   com_task_runner->PostTask( | 419   com_task_runner->PostTask( | 
| 456       FROM_HERE, | 420       FROM_HERE, | 
| 457       Bind([](TaskSchedulerSingleThreadTaskRunnerManagerTestWin* test_harness, | 421       BindOnce( | 
| 458               HWND* hwnd) { *hwnd = test_harness->CreateTestWindow(); }, | 422           [](TaskSchedulerSingleThreadTaskRunnerManagerTestWin* test_harness, | 
| 459            Unretained(this), &hwnd)); | 423              HWND* hwnd) { *hwnd = test_harness->CreateTestWindow(); }, | 
|  | 424           Unretained(this), &hwnd)); | 
| 460 | 425 | 
| 461   task_tracker_.Flush(); | 426   task_tracker_.Flush(); | 
| 462 | 427 | 
| 463   ASSERT_NE(hwnd, nullptr); | 428   ASSERT_NE(hwnd, nullptr); | 
| 464   // If the message pump isn't running, we will hang here. This simulates how | 429   // If the message pump isn't running, we will hang here. This simulates how | 
| 465   // COM would receive a callback with its own message HWND. | 430   // COM would receive a callback with its own message HWND. | 
| 466   SendMessage(hwnd, WM_USER, 0, 0); | 431   SendMessage(hwnd, WM_USER, 0, 0); | 
| 467 | 432 | 
| 468   com_task_runner->PostTask( | 433   com_task_runner->PostTask( | 
| 469       FROM_HERE, Bind([](HWND hwnd) { ::DestroyWindow(hwnd); }, hwnd)); | 434       FROM_HERE, BindOnce([](HWND hwnd) { ::DestroyWindow(hwnd); }, hwnd)); | 
| 470 | 435 | 
| 471   task_tracker_.Shutdown(); | 436   task_tracker_.Shutdown(); | 
| 472 } | 437 } | 
| 473 | 438 | 
| 474 #endif  // defined(OS_WIN) | 439 #endif  // defined(OS_WIN) | 
| 475 | 440 | 
| 476 namespace { | 441 namespace { | 
| 477 | 442 | 
| 478 class TaskSchedulerSingleThreadTaskRunnerManagerStartTest | 443 class TaskSchedulerSingleThreadTaskRunnerManagerStartTest | 
| 479     : public TaskSchedulerSingleThreadTaskRunnerManagerTest { | 444     : public TaskSchedulerSingleThreadTaskRunnerManagerTest { | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 490 | 455 | 
| 491 }  // namespace | 456 }  // namespace | 
| 492 | 457 | 
| 493 // Verify that a task posted before Start() doesn't run until Start() is called. | 458 // Verify that a task posted before Start() doesn't run until Start() is called. | 
| 494 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerStartTest, | 459 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerStartTest, | 
| 495        PostTaskBeforeStart) { | 460        PostTaskBeforeStart) { | 
| 496   AtomicFlag manager_started; | 461   AtomicFlag manager_started; | 
| 497   WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 462   WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 
| 498                              WaitableEvent::InitialState::NOT_SIGNALED); | 463                              WaitableEvent::InitialState::NOT_SIGNALED); | 
| 499   single_thread_task_runner_manager_ | 464   single_thread_task_runner_manager_ | 
| 500       ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()) | 465       ->CreateSingleThreadTaskRunnerWithTraits("A", ThreadPriority::NORMAL, | 
|  | 466                                                TaskTraits()) | 
| 501       ->PostTask( | 467       ->PostTask( | 
| 502           FROM_HERE, | 468           FROM_HERE, | 
| 503           Bind( | 469           BindOnce( | 
| 504               [](WaitableEvent* task_running, AtomicFlag* manager_started) { | 470               [](WaitableEvent* task_running, AtomicFlag* manager_started) { | 
| 505                 task_running->Signal(); | 471                 task_running->Signal(); | 
| 506 | 472 | 
| 507                 // The task should not run before Start(). | 473                 // The task should not run before Start(). | 
| 508                 EXPECT_TRUE(manager_started->IsSet()); | 474                 EXPECT_TRUE(manager_started->IsSet()); | 
| 509               }, | 475               }, | 
| 510               Unretained(&task_running), Unretained(&manager_started))); | 476               Unretained(&task_running), Unretained(&manager_started))); | 
| 511 | 477 | 
| 512   // Wait a little bit to make sure that the task isn't scheduled before start. | 478   // Wait a little bit to make sure that the task isn't scheduled before start. | 
| 513   // Note: This test won't catch a case where the task is scheduled between | 479   // Note: This test won't catch a case where the task is scheduled between | 
| 514   // setting |manager_started| and calling Start(). However, we expect the test | 480   // setting |manager_started| and calling Start(). However, we expect the test | 
| 515   // to be flaky if the tested code allows that to happen. | 481   // to be flaky if the tested code allows that to happen. | 
| 516   PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 482   PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 
| 517   manager_started.Set(); | 483   manager_started.Set(); | 
| 518   single_thread_task_runner_manager_->Start(); | 484   single_thread_task_runner_manager_->Start(); | 
| 519 | 485 | 
| 520   // This should not hang if the task is scheduled after Start(). | 486   // This should not hang if the task is scheduled after Start(). | 
| 521   task_running.Wait(); | 487   task_running.Wait(); | 
| 522 } | 488 } | 
| 523 | 489 | 
| 524 }  // namespace internal | 490 }  // namespace internal | 
| 525 }  // namespace base | 491 }  // namespace base | 
| OLD | NEW | 
|---|