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/lock.h" | 9 #include "base/synchronization/lock.h" |
10 #include "base/synchronization/waitable_event.h" | 10 #include "base/synchronization/waitable_event.h" |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
273 void Run() override { | 273 void Run() override { |
274 run_started_event_.Signal(); | 274 run_started_event_.Signal(); |
275 manager_to_join_->JoinForTesting(); | 275 manager_to_join_->JoinForTesting(); |
276 } | 276 } |
277 | 277 |
278 void WaitForRunToStart() { run_started_event_.Wait(); } | 278 void WaitForRunToStart() { run_started_event_.Wait(); } |
279 | 279 |
280 private: | 280 private: |
281 SchedulerSingleThreadTaskRunnerManager* const manager_to_join_; | 281 SchedulerSingleThreadTaskRunnerManager* const manager_to_join_; |
282 WaitableEvent run_started_event_; | 282 WaitableEvent run_started_event_; |
283 | |
283 DISALLOW_COPY_AND_ASSIGN(CallJoinFromDifferentThread); | 284 DISALLOW_COPY_AND_ASSIGN(CallJoinFromDifferentThread); |
284 }; | 285 }; |
285 | 286 |
286 class TaskSchedulerSingleThreadTaskRunnerManagerJoinTest | 287 class TaskSchedulerSingleThreadTaskRunnerManagerJoinTest |
287 : public TaskSchedulerSingleThreadTaskRunnerManagerTest { | 288 : public TaskSchedulerSingleThreadTaskRunnerManagerTest { |
288 public: | 289 public: |
289 TaskSchedulerSingleThreadTaskRunnerManagerJoinTest() = default; | 290 TaskSchedulerSingleThreadTaskRunnerManagerJoinTest() = default; |
290 ~TaskSchedulerSingleThreadTaskRunnerManagerJoinTest() override = default; | 291 ~TaskSchedulerSingleThreadTaskRunnerManagerJoinTest() override = default; |
291 | 292 |
292 protected: | 293 protected: |
293 void TearDownSingleThreadTaskRunnerManager() override { | 294 void TearDownSingleThreadTaskRunnerManager() override { |
294 // The tests themselves are responsible for calling JoinForTesting(). | 295 // The tests themselves are responsible for calling JoinForTesting(). |
295 single_thread_task_runner_manager_.reset(); | 296 single_thread_task_runner_manager_.reset(); |
296 } | 297 } |
297 | 298 |
298 private: | 299 private: |
299 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest); | 300 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest); |
300 }; | 301 }; |
301 | 302 |
302 } // namespace | 303 } // namespace |
303 | 304 |
304 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, ConcurrentJoin) { | 305 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, ConcurrentJoin) { |
306 // Exercises the codepath where the workers are unavailable for unregistration | |
307 // because of a Join call. | |
305 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 308 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
306 WaitableEvent::InitialState::NOT_SIGNALED); | 309 WaitableEvent::InitialState::NOT_SIGNALED); |
307 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 310 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
308 WaitableEvent::InitialState::NOT_SIGNALED); | 311 WaitableEvent::InitialState::NOT_SIGNALED); |
309 | 312 |
310 { | 313 { |
311 auto task_runner = single_thread_task_runner_manager_ | 314 auto task_runner = single_thread_task_runner_manager_ |
312 ->CreateSingleThreadTaskRunnerWithTraits( | 315 ->CreateSingleThreadTaskRunnerWithTraits( |
313 TaskTraits().WithBaseSyncPrimitives()); | 316 TaskTraits().WithBaseSyncPrimitives()); |
314 EXPECT_TRUE(task_runner->PostTask( | 317 EXPECT_TRUE(task_runner->PostTask( |
315 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_running)))); | 318 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_running)))); |
316 EXPECT_TRUE(task_runner->PostTask( | 319 EXPECT_TRUE(task_runner->PostTask( |
317 FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 320 FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&task_blocking)))); |
318 } | 321 } |
319 | 322 |
320 task_running.Wait(); | 323 task_running.Wait(); |
321 CallJoinFromDifferentThread join_from_different_thread( | 324 CallJoinFromDifferentThread join_from_different_thread( |
322 single_thread_task_runner_manager_.get()); | 325 single_thread_task_runner_manager_.get()); |
323 join_from_different_thread.Start(); | 326 join_from_different_thread.Start(); |
324 join_from_different_thread.WaitForRunToStart(); | 327 join_from_different_thread.WaitForRunToStart(); |
325 task_blocking.Signal(); | 328 task_blocking.Signal(); |
326 join_from_different_thread.Join(); | 329 join_from_different_thread.Join(); |
327 } | 330 } |
328 | 331 |
329 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, | 332 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, |
330 ConcurrentJoinExtraSkippedTask) { | 333 ConcurrentJoinExtraSkippedTask) { |
334 // Tests to make sure that tasks are properly cleaned up at Join, allowing | |
335 // SingleThreadTaskRunners to unregister themselves. | |
331 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 336 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
332 WaitableEvent::InitialState::NOT_SIGNALED); | 337 WaitableEvent::InitialState::NOT_SIGNALED); |
333 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 338 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
334 WaitableEvent::InitialState::NOT_SIGNALED); | 339 WaitableEvent::InitialState::NOT_SIGNALED); |
335 | 340 |
336 { | 341 { |
337 auto task_runner = single_thread_task_runner_manager_ | 342 auto task_runner = single_thread_task_runner_manager_ |
338 ->CreateSingleThreadTaskRunnerWithTraits( | 343 ->CreateSingleThreadTaskRunnerWithTraits( |
339 TaskTraits().WithBaseSyncPrimitives()); | 344 TaskTraits().WithBaseSyncPrimitives()); |
340 EXPECT_TRUE(task_runner->PostTask( | 345 EXPECT_TRUE(task_runner->PostTask( |
341 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_running)))); | 346 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_running)))); |
342 EXPECT_TRUE(task_runner->PostTask( | 347 EXPECT_TRUE(task_runner->PostTask( |
343 FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 348 FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&task_blocking)))); |
344 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, Bind(&DoNothing))); | 349 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, Bind(&DoNothing))); |
gab
2017/03/15 20:45:12
Then wouldn't you want to bind something here that
robliao
2017/03/15 20:49:30
If the task isn't deleted, the SingleThreadTaskRun
| |
345 } | 350 } |
346 | 351 |
347 task_running.Wait(); | 352 task_running.Wait(); |
348 CallJoinFromDifferentThread join_from_different_thread( | 353 CallJoinFromDifferentThread join_from_different_thread( |
349 single_thread_task_runner_manager_.get()); | 354 single_thread_task_runner_manager_.get()); |
350 join_from_different_thread.Start(); | 355 join_from_different_thread.Start(); |
351 join_from_different_thread.WaitForRunToStart(); | 356 join_from_different_thread.WaitForRunToStart(); |
352 task_blocking.Signal(); | 357 task_blocking.Signal(); |
353 join_from_different_thread.Join(); | 358 join_from_different_thread.Join(); |
354 } | 359 } |
355 | 360 |
356 } // namespace internal | 361 } // namespace internal |
357 } // namespace base | 362 } // namespace base |
OLD | NEW |