OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/threading/sequenced_worker_pool.h" | 5 #include "base/threading/sequenced_worker_pool.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 // finishes running. | 152 // finishes running. |
153 void PostRepostingBlockingTask( | 153 void PostRepostingBlockingTask( |
154 const scoped_refptr<SequencedWorkerPool>& pool, | 154 const scoped_refptr<SequencedWorkerPool>& pool, |
155 const SequencedWorkerPool::SequenceToken& token) { | 155 const SequencedWorkerPool::SequenceToken& token) { |
156 Closure reposting_task = | 156 Closure reposting_task = |
157 base::Bind(&TestTracker::PostRepostingBlockingTask, this, pool, token); | 157 base::Bind(&TestTracker::PostRepostingBlockingTask, this, pool, token); |
158 pool->PostSequencedWorkerTaskWithShutdownBehavior(token, | 158 pool->PostSequencedWorkerTaskWithShutdownBehavior(token, |
159 FROM_HERE, reposting_task, SequencedWorkerPool::BLOCK_SHUTDOWN); | 159 FROM_HERE, reposting_task, SequencedWorkerPool::BLOCK_SHUTDOWN); |
160 } | 160 } |
161 | 161 |
| 162 void PostBlockingTaskThenUnblockThreads( |
| 163 const scoped_refptr<SequencedWorkerPool>& pool, |
| 164 ThreadBlocker* blocker, |
| 165 size_t threads_to_wake) { |
| 166 Closure arbitrary_task = base::Bind(&TestTracker::FastTask, this, 0); |
| 167 pool->PostWorkerTaskWithShutdownBehavior( |
| 168 FROM_HERE, arbitrary_task, SequencedWorkerPool::BLOCK_SHUTDOWN); |
| 169 blocker->Unblock(threads_to_wake); |
| 170 } |
| 171 |
162 // Waits until the given number of tasks have started executing. | 172 // Waits until the given number of tasks have started executing. |
163 void WaitUntilTasksBlocked(size_t count) { | 173 void WaitUntilTasksBlocked(size_t count) { |
164 { | 174 { |
165 base::AutoLock lock(lock_); | 175 base::AutoLock lock(lock_); |
166 while (started_events_ < count) | 176 while (started_events_ < count) |
167 cond_var_.Wait(); | 177 cond_var_.Wait(); |
168 } | 178 } |
169 cond_var_.Signal(); | 179 cond_var_.Signal(); |
170 } | 180 } |
171 | 181 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 } | 290 } |
281 | 291 |
282 private: | 292 private: |
283 MessageLoop message_loop_; | 293 MessageLoop message_loop_; |
284 scoped_ptr<SequencedWorkerPoolOwner> pool_owner_; | 294 scoped_ptr<SequencedWorkerPoolOwner> pool_owner_; |
285 const scoped_refptr<TestTracker> tracker_; | 295 const scoped_refptr<TestTracker> tracker_; |
286 }; | 296 }; |
287 | 297 |
288 // Checks that the given number of entries are in the tasks to complete of | 298 // Checks that the given number of entries are in the tasks to complete of |
289 // the given tracker, and then signals the given event the given number of | 299 // the given tracker, and then signals the given event the given number of |
290 // times. This is used to wakt up blocked background threads before blocking | 300 // times. This is used to wake up blocked background threads before blocking |
291 // on shutdown. | 301 // on shutdown. |
292 void EnsureTasksToCompleteCountAndUnblock(scoped_refptr<TestTracker> tracker, | 302 void EnsureTasksToCompleteCountAndUnblock(scoped_refptr<TestTracker> tracker, |
293 size_t expected_tasks_to_complete, | 303 size_t expected_tasks_to_complete, |
294 ThreadBlocker* blocker, | 304 ThreadBlocker* blocker, |
295 size_t threads_to_awake) { | 305 size_t threads_to_awake) { |
296 EXPECT_EQ( | 306 EXPECT_EQ( |
297 expected_tasks_to_complete, | 307 expected_tasks_to_complete, |
298 tracker->WaitUntilTasksComplete(expected_tasks_to_complete).size()); | 308 tracker->WaitUntilTasksComplete(expected_tasks_to_complete).size()); |
299 | 309 |
300 blocker->Unblock(threads_to_awake); | 310 blocker->Unblock(threads_to_awake); |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 pool()->Shutdown(kNumNewBlockingTasksToAllow); | 586 pool()->Shutdown(kNumNewBlockingTasksToAllow); |
577 | 587 |
578 // Ensure that the correct number of tasks actually got run. | 588 // Ensure that the correct number of tasks actually got run. |
579 tracker()->WaitUntilTasksComplete(static_cast<size_t>( | 589 tracker()->WaitUntilTasksComplete(static_cast<size_t>( |
580 kNumBlockTasks + kNumQueuedTasks + kNumNewBlockingTasksToAllow)); | 590 kNumBlockTasks + kNumQueuedTasks + kNumNewBlockingTasksToAllow)); |
581 | 591 |
582 // Clean up the task IDs we added and go home. | 592 // Clean up the task IDs we added and go home. |
583 tracker()->ClearCompleteSequence(); | 593 tracker()->ClearCompleteSequence(); |
584 } | 594 } |
585 | 595 |
| 596 // Tests that blocking tasks can still be posted during shutdown, as long as |
| 597 // the task is not being posted within the context of a running task. |
| 598 TEST_F(SequencedWorkerPoolTest, |
| 599 AllowsBlockingTasksDuringShutdownOutsideOfRunningTask) { |
| 600 EnsureAllWorkersCreated(); |
| 601 ThreadBlocker blocker; |
| 602 |
| 603 // Start tasks to take all the threads and block them. |
| 604 const int kNumBlockTasks = static_cast<int>(kNumWorkerThreads); |
| 605 for (int i = 0; i < kNumBlockTasks; ++i) { |
| 606 EXPECT_TRUE(pool()->PostWorkerTask( |
| 607 FROM_HERE, |
| 608 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker))); |
| 609 } |
| 610 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); |
| 611 |
| 612 // Setup to open the floodgates from within Shutdown(). |
| 613 SetWillWaitForShutdownCallback( |
| 614 base::Bind(&TestTracker::PostBlockingTaskThenUnblockThreads, |
| 615 scoped_refptr<TestTracker>(tracker()), pool(), &blocker, |
| 616 kNumWorkerThreads)); |
| 617 pool()->Shutdown(kNumWorkerThreads + 1); |
| 618 |
| 619 // Ensure that the correct number of tasks actually got run. |
| 620 tracker()->WaitUntilTasksComplete(static_cast<size_t>(kNumWorkerThreads + 1)); |
| 621 tracker()->ClearCompleteSequence(); |
| 622 } |
| 623 |
586 // Tests that unrun tasks are discarded properly according to their shutdown | 624 // Tests that unrun tasks are discarded properly according to their shutdown |
587 // mode. | 625 // mode. |
588 TEST_F(SequencedWorkerPoolTest, DiscardOnShutdown) { | 626 TEST_F(SequencedWorkerPoolTest, DiscardOnShutdown) { |
589 // Start tasks to take all the threads and block them. | 627 // Start tasks to take all the threads and block them. |
590 EnsureAllWorkersCreated(); | 628 EnsureAllWorkersCreated(); |
591 ThreadBlocker blocker; | 629 ThreadBlocker blocker; |
592 for (size_t i = 0; i < kNumWorkerThreads; i++) { | 630 for (size_t i = 0; i < kNumWorkerThreads; i++) { |
593 pool()->PostWorkerTask(FROM_HERE, | 631 pool()->PostWorkerTask(FROM_HERE, |
594 base::Bind(&TestTracker::BlockTask, | 632 base::Bind(&TestTracker::BlockTask, |
595 tracker(), i, &blocker)); | 633 tracker(), i, &blocker)); |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
986 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerTest, | 1024 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerTest, |
987 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 1025 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); |
988 | 1026 |
989 INSTANTIATE_TYPED_TEST_CASE_P( | 1027 INSTANTIATE_TYPED_TEST_CASE_P( |
990 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest, | 1028 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest, |
991 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 1029 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); |
992 | 1030 |
993 } // namespace | 1031 } // namespace |
994 | 1032 |
995 } // namespace base | 1033 } // namespace base |
OLD | NEW |