Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: base/threading/sequenced_worker_pool.cc

Issue 2637843002: Migrate base::TaskRunner from Closure to OnceClosure (Closed)
Patch Set: rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/threading/sequenced_worker_pool.h ('k') | base/threading/worker_pool.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <stdint.h> 7 #include <stdint.h>
8 8
9 #include <list> 9 #include <list>
10 #include <map> 10 #include <map>
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 86
87 explicit SequencedTask(const tracked_objects::Location& from_here) 87 explicit SequencedTask(const tracked_objects::Location& from_here)
88 : base::TrackingInfo(from_here, TimeTicks()), 88 : base::TrackingInfo(from_here, TimeTicks()),
89 sequence_token_id(0), 89 sequence_token_id(0),
90 trace_id(0), 90 trace_id(0),
91 sequence_task_number(0), 91 sequence_task_number(0),
92 shutdown_behavior(SequencedWorkerPool::BLOCK_SHUTDOWN) {} 92 shutdown_behavior(SequencedWorkerPool::BLOCK_SHUTDOWN) {}
93 93
94 ~SequencedTask() {} 94 ~SequencedTask() {}
95 95
96 SequencedTask(SequencedTask&&) = default;
97 SequencedTask& operator=(SequencedTask&&) = default;
98
96 int sequence_token_id; 99 int sequence_token_id;
97 int trace_id; 100 int trace_id;
98 int64_t sequence_task_number; 101 int64_t sequence_task_number;
99 SequencedWorkerPool::WorkerShutdown shutdown_behavior; 102 SequencedWorkerPool::WorkerShutdown shutdown_behavior;
100 tracked_objects::Location posted_from; 103 tracked_objects::Location posted_from;
101 Closure task; 104 OnceClosure task;
102 105
103 // Non-delayed tasks and delayed tasks are managed together by time-to-run 106 // Non-delayed tasks and delayed tasks are managed together by time-to-run
104 // order. We calculate the time by adding the posted time and the given delay. 107 // order. We calculate the time by adding the posted time and the given delay.
105 TimeTicks time_to_run; 108 TimeTicks time_to_run;
106 }; 109 };
107 110
108 struct SequencedTaskLessThan { 111 struct SequencedTaskLessThan {
109 public: 112 public:
110 bool operator()(const SequencedTask& lhs, const SequencedTask& rhs) const { 113 bool operator()(const SequencedTask& lhs, const SequencedTask& rhs) const {
111 if (lhs.time_to_run < rhs.time_to_run) 114 if (lhs.time_to_run < rhs.time_to_run)
(...skipping 21 matching lines...) Expand all
133 // 136 //
134 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). 137 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner).
135 class SequencedWorkerPoolTaskRunner : public TaskRunner { 138 class SequencedWorkerPoolTaskRunner : public TaskRunner {
136 public: 139 public:
137 SequencedWorkerPoolTaskRunner( 140 SequencedWorkerPoolTaskRunner(
138 scoped_refptr<SequencedWorkerPool> pool, 141 scoped_refptr<SequencedWorkerPool> pool,
139 SequencedWorkerPool::WorkerShutdown shutdown_behavior); 142 SequencedWorkerPool::WorkerShutdown shutdown_behavior);
140 143
141 // TaskRunner implementation 144 // TaskRunner implementation
142 bool PostDelayedTask(const tracked_objects::Location& from_here, 145 bool PostDelayedTask(const tracked_objects::Location& from_here,
143 Closure task, 146 OnceClosure task,
144 TimeDelta delay) override; 147 TimeDelta delay) override;
145 bool RunsTasksOnCurrentThread() const override; 148 bool RunsTasksOnCurrentThread() const override;
146 149
147 private: 150 private:
148 ~SequencedWorkerPoolTaskRunner() override; 151 ~SequencedWorkerPoolTaskRunner() override;
149 152
150 const scoped_refptr<SequencedWorkerPool> pool_; 153 const scoped_refptr<SequencedWorkerPool> pool_;
151 154
152 const SequencedWorkerPool::WorkerShutdown shutdown_behavior_; 155 const SequencedWorkerPool::WorkerShutdown shutdown_behavior_;
153 156
154 DISALLOW_COPY_AND_ASSIGN(SequencedWorkerPoolTaskRunner); 157 DISALLOW_COPY_AND_ASSIGN(SequencedWorkerPoolTaskRunner);
155 }; 158 };
156 159
157 SequencedWorkerPoolTaskRunner::SequencedWorkerPoolTaskRunner( 160 SequencedWorkerPoolTaskRunner::SequencedWorkerPoolTaskRunner(
158 scoped_refptr<SequencedWorkerPool> pool, 161 scoped_refptr<SequencedWorkerPool> pool,
159 SequencedWorkerPool::WorkerShutdown shutdown_behavior) 162 SequencedWorkerPool::WorkerShutdown shutdown_behavior)
160 : pool_(std::move(pool)), shutdown_behavior_(shutdown_behavior) {} 163 : pool_(std::move(pool)), shutdown_behavior_(shutdown_behavior) {}
161 164
162 SequencedWorkerPoolTaskRunner::~SequencedWorkerPoolTaskRunner() { 165 SequencedWorkerPoolTaskRunner::~SequencedWorkerPoolTaskRunner() {
163 } 166 }
164 167
165 bool SequencedWorkerPoolTaskRunner::PostDelayedTask( 168 bool SequencedWorkerPoolTaskRunner::PostDelayedTask(
166 const tracked_objects::Location& from_here, 169 const tracked_objects::Location& from_here,
167 Closure task, 170 OnceClosure task,
168 TimeDelta delay) { 171 TimeDelta delay) {
169 if (delay.is_zero()) { 172 if (delay.is_zero()) {
170 return pool_->PostWorkerTaskWithShutdownBehavior(from_here, std::move(task), 173 return pool_->PostWorkerTaskWithShutdownBehavior(from_here, std::move(task),
171 shutdown_behavior_); 174 shutdown_behavior_);
172 } 175 }
173 return pool_->PostDelayedWorkerTask(from_here, std::move(task), delay); 176 return pool_->PostDelayedWorkerTask(from_here, std::move(task), delay);
174 } 177 }
175 178
176 bool SequencedWorkerPoolTaskRunner::RunsTasksOnCurrentThread() const { 179 bool SequencedWorkerPoolTaskRunner::RunsTasksOnCurrentThread() const {
177 return pool_->RunsTasksOnCurrentThread(); 180 return pool_->RunsTasksOnCurrentThread();
178 } 181 }
179 182
180 } // namespace 183 } // namespace
181 184
182 // SequencedWorkerPool::PoolSequencedTaskRunner ------------------------------ 185 // SequencedWorkerPool::PoolSequencedTaskRunner ------------------------------
183 // A SequencedTaskRunner which posts tasks to a SequencedWorkerPool with a 186 // A SequencedTaskRunner which posts tasks to a SequencedWorkerPool with a
184 // fixed sequence token. 187 // fixed sequence token.
185 // 188 //
186 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). 189 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner).
187 class SequencedWorkerPool::PoolSequencedTaskRunner 190 class SequencedWorkerPool::PoolSequencedTaskRunner
188 : public SequencedTaskRunner { 191 : public SequencedTaskRunner {
189 public: 192 public:
190 PoolSequencedTaskRunner( 193 PoolSequencedTaskRunner(
191 scoped_refptr<SequencedWorkerPool> pool, 194 scoped_refptr<SequencedWorkerPool> pool,
192 SequencedWorkerPool::SequenceToken token, 195 SequencedWorkerPool::SequenceToken token,
193 SequencedWorkerPool::WorkerShutdown shutdown_behavior); 196 SequencedWorkerPool::WorkerShutdown shutdown_behavior);
194 197
195 // TaskRunner implementation 198 // TaskRunner implementation
196 bool PostDelayedTask(const tracked_objects::Location& from_here, 199 bool PostDelayedTask(const tracked_objects::Location& from_here,
197 Closure task, 200 OnceClosure task,
198 TimeDelta delay) override; 201 TimeDelta delay) override;
199 bool RunsTasksOnCurrentThread() const override; 202 bool RunsTasksOnCurrentThread() const override;
200 203
201 // SequencedTaskRunner implementation 204 // SequencedTaskRunner implementation
202 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, 205 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
203 Closure task, 206 OnceClosure task,
204 TimeDelta delay) override; 207 TimeDelta delay) override;
205 208
206 private: 209 private:
207 ~PoolSequencedTaskRunner() override; 210 ~PoolSequencedTaskRunner() override;
208 211
209 const scoped_refptr<SequencedWorkerPool> pool_; 212 const scoped_refptr<SequencedWorkerPool> pool_;
210 213
211 const SequencedWorkerPool::SequenceToken token_; 214 const SequencedWorkerPool::SequenceToken token_;
212 215
213 const SequencedWorkerPool::WorkerShutdown shutdown_behavior_; 216 const SequencedWorkerPool::WorkerShutdown shutdown_behavior_;
214 217
215 DISALLOW_COPY_AND_ASSIGN(PoolSequencedTaskRunner); 218 DISALLOW_COPY_AND_ASSIGN(PoolSequencedTaskRunner);
216 }; 219 };
217 220
218 SequencedWorkerPool::PoolSequencedTaskRunner:: 221 SequencedWorkerPool::PoolSequencedTaskRunner::
219 PoolSequencedTaskRunner( 222 PoolSequencedTaskRunner(
220 scoped_refptr<SequencedWorkerPool> pool, 223 scoped_refptr<SequencedWorkerPool> pool,
221 SequencedWorkerPool::SequenceToken token, 224 SequencedWorkerPool::SequenceToken token,
222 SequencedWorkerPool::WorkerShutdown shutdown_behavior) 225 SequencedWorkerPool::WorkerShutdown shutdown_behavior)
223 : pool_(std::move(pool)), 226 : pool_(std::move(pool)),
224 token_(token), 227 token_(token),
225 shutdown_behavior_(shutdown_behavior) {} 228 shutdown_behavior_(shutdown_behavior) {}
226 229
227 SequencedWorkerPool::PoolSequencedTaskRunner:: 230 SequencedWorkerPool::PoolSequencedTaskRunner::
228 ~PoolSequencedTaskRunner() = default; 231 ~PoolSequencedTaskRunner() = default;
229 232
230 bool SequencedWorkerPool::PoolSequencedTaskRunner::PostDelayedTask( 233 bool SequencedWorkerPool::PoolSequencedTaskRunner::PostDelayedTask(
231 const tracked_objects::Location& from_here, 234 const tracked_objects::Location& from_here,
232 Closure task, 235 OnceClosure task,
233 TimeDelta delay) { 236 TimeDelta delay) {
234 if (delay.is_zero()) { 237 if (delay.is_zero()) {
235 return pool_->PostSequencedWorkerTaskWithShutdownBehavior( 238 return pool_->PostSequencedWorkerTaskWithShutdownBehavior(
236 token_, from_here, std::move(task), shutdown_behavior_); 239 token_, from_here, std::move(task), shutdown_behavior_);
237 } 240 }
238 return pool_->PostDelayedSequencedWorkerTask(token_, from_here, 241 return pool_->PostDelayedSequencedWorkerTask(token_, from_here,
239 std::move(task), delay); 242 std::move(task), delay);
240 } 243 }
241 244
242 bool SequencedWorkerPool::PoolSequencedTaskRunner:: 245 bool SequencedWorkerPool::PoolSequencedTaskRunner::
243 RunsTasksOnCurrentThread() const { 246 RunsTasksOnCurrentThread() const {
244 return pool_->IsRunningSequenceOnCurrentThread(token_); 247 return pool_->IsRunningSequenceOnCurrentThread(token_);
245 } 248 }
246 249
247 bool SequencedWorkerPool::PoolSequencedTaskRunner::PostNonNestableDelayedTask( 250 bool SequencedWorkerPool::PoolSequencedTaskRunner::PostNonNestableDelayedTask(
248 const tracked_objects::Location& from_here, 251 const tracked_objects::Location& from_here,
249 Closure task, 252 OnceClosure task,
250 TimeDelta delay) { 253 TimeDelta delay) {
251 // There's no way to run nested tasks, so simply forward to 254 // There's no way to run nested tasks, so simply forward to
252 // PostDelayedTask. 255 // PostDelayedTask.
253 return PostDelayedTask(from_here, std::move(task), delay); 256 return PostDelayedTask(from_here, std::move(task), delay);
254 } 257 }
255 258
256 // Worker --------------------------------------------------------------------- 259 // Worker ---------------------------------------------------------------------
257 260
258 class SequencedWorkerPool::Worker : public SimpleThread { 261 class SequencedWorkerPool::Worker : public SimpleThread {
259 public: 262 public:
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 345
343 SequenceToken GetNamedSequenceToken(const std::string& name); 346 SequenceToken GetNamedSequenceToken(const std::string& name);
344 347
345 // This function accepts a name and an ID. If the name is null, the 348 // This function accepts a name and an ID. If the name is null, the
346 // token ID is used. This allows us to implement the optional name lookup 349 // token ID is used. This allows us to implement the optional name lookup
347 // from a single function without having to enter the lock a separate time. 350 // from a single function without having to enter the lock a separate time.
348 bool PostTask(const std::string* optional_token_name, 351 bool PostTask(const std::string* optional_token_name,
349 SequenceToken sequence_token, 352 SequenceToken sequence_token,
350 WorkerShutdown shutdown_behavior, 353 WorkerShutdown shutdown_behavior,
351 const tracked_objects::Location& from_here, 354 const tracked_objects::Location& from_here,
352 Closure task, 355 OnceClosure task,
353 TimeDelta delay); 356 TimeDelta delay);
354 357
355 bool RunsTasksOnCurrentThread() const; 358 bool RunsTasksOnCurrentThread() const;
356 359
357 bool IsRunningSequenceOnCurrentThread(SequenceToken sequence_token) const; 360 bool IsRunningSequenceOnCurrentThread(SequenceToken sequence_token) const;
358 361
359 void CleanupForTesting(); 362 void CleanupForTesting();
360 363
361 void SignalHasWorkForTesting(); 364 void SignalHasWorkForTesting();
362 365
(...skipping 24 matching lines...) Expand all
387 // Clears ScheduledTasks in |tasks_to_delete| while ensuring that 390 // Clears ScheduledTasks in |tasks_to_delete| while ensuring that
388 // |this_worker| has the desired task info context during ~ScheduledTask() to 391 // |this_worker| has the desired task info context during ~ScheduledTask() to
389 // allow sequence-checking. 392 // allow sequence-checking.
390 void DeleteWithoutLock(std::vector<SequencedTask>* tasks_to_delete, 393 void DeleteWithoutLock(std::vector<SequencedTask>* tasks_to_delete,
391 Worker* this_worker); 394 Worker* this_worker);
392 395
393 // Helper used by PostTask() to complete the work when redirection is on. 396 // Helper used by PostTask() to complete the work when redirection is on.
394 // Returns true if the task may run at some point in the future and false if 397 // Returns true if the task may run at some point in the future and false if
395 // it will definitely not run. 398 // it will definitely not run.
396 // Coalesce upon resolution of http://crbug.com/622400. 399 // Coalesce upon resolution of http://crbug.com/622400.
397 bool PostTaskToTaskScheduler(const SequencedTask& sequenced, 400 bool PostTaskToTaskScheduler(SequencedTask sequenced, const TimeDelta& delay);
398 const TimeDelta& delay);
399 401
400 // Returns the TaskScheduler TaskRunner for the specified |sequence_token_id| 402 // Returns the TaskScheduler TaskRunner for the specified |sequence_token_id|
401 // and |traits|. 403 // and |traits|.
402 scoped_refptr<TaskRunner> GetTaskSchedulerTaskRunner( 404 scoped_refptr<TaskRunner> GetTaskSchedulerTaskRunner(
403 int sequence_token_id, 405 int sequence_token_id,
404 const TaskTraits& traits); 406 const TaskTraits& traits);
405 407
406 // Called from within the lock, this converts the given token name into a 408 // Called from within the lock, this converts the given token name into a
407 // token ID, creating a new one if necessary. 409 // token ID, creating a new one if necessary.
408 int LockedGetNamedTokenID(const std::string& name); 410 int LockedGetNamedTokenID(const std::string& name);
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 SequencedWorkerPool::Inner::GetNamedSequenceToken(const std::string& name) { 688 SequencedWorkerPool::Inner::GetNamedSequenceToken(const std::string& name) {
687 AutoLock lock(lock_); 689 AutoLock lock(lock_);
688 return SequenceToken(LockedGetNamedTokenID(name)); 690 return SequenceToken(LockedGetNamedTokenID(name));
689 } 691 }
690 692
691 bool SequencedWorkerPool::Inner::PostTask( 693 bool SequencedWorkerPool::Inner::PostTask(
692 const std::string* optional_token_name, 694 const std::string* optional_token_name,
693 SequenceToken sequence_token, 695 SequenceToken sequence_token,
694 WorkerShutdown shutdown_behavior, 696 WorkerShutdown shutdown_behavior,
695 const tracked_objects::Location& from_here, 697 const tracked_objects::Location& from_here,
696 Closure task, 698 OnceClosure task,
697 TimeDelta delay) { 699 TimeDelta delay) {
698 DCHECK(task); 700 DCHECK(task);
699 701
700 // TODO(fdoray): Uncomment this DCHECK. It is initially commented to avoid a 702 // TODO(fdoray): Uncomment this DCHECK. It is initially commented to avoid a
701 // revert of the CL that adds debug::DumpWithoutCrashing() if it fails on the 703 // revert of the CL that adds debug::DumpWithoutCrashing() if it fails on the
702 // waterfall. https://crbug.com/622400 704 // waterfall. https://crbug.com/622400
703 // DCHECK_NE(AllPoolsState::POST_TASK_DISABLED, g_all_pools_state); 705 // DCHECK_NE(AllPoolsState::POST_TASK_DISABLED, g_all_pools_state);
704 if (g_all_pools_state == AllPoolsState::POST_TASK_DISABLED) 706 if (g_all_pools_state == AllPoolsState::POST_TASK_DISABLED)
705 debug::DumpWithoutCrashing(); 707 debug::DumpWithoutCrashing();
706 708
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 TRACE_ID_MANGLE(GetTaskTraceID(sequenced, static_cast<void*>(this))), 749 TRACE_ID_MANGLE(GetTaskTraceID(sequenced, static_cast<void*>(this))),
748 TRACE_EVENT_FLAG_FLOW_OUT); 750 TRACE_EVENT_FLAG_FLOW_OUT);
749 751
750 sequenced.sequence_task_number = LockedGetNextSequenceTaskNumber(); 752 sequenced.sequence_task_number = LockedGetNextSequenceTaskNumber();
751 753
752 // Now that we have the lock, apply the named token rules. 754 // Now that we have the lock, apply the named token rules.
753 if (optional_token_name) 755 if (optional_token_name)
754 sequenced.sequence_token_id = LockedGetNamedTokenID(*optional_token_name); 756 sequenced.sequence_token_id = LockedGetNamedTokenID(*optional_token_name);
755 757
756 if (g_all_pools_state == AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) { 758 if (g_all_pools_state == AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) {
757 if (!PostTaskToTaskScheduler(sequenced, delay)) 759 if (!PostTaskToTaskScheduler(std::move(sequenced), delay))
758 return false; 760 return false;
759 } else { 761 } else {
760 pending_tasks_.insert(sequenced); 762 SequencedWorkerPool::WorkerShutdown shutdown_behavior =
763 sequenced.shutdown_behavior;
764 pending_tasks_.insert(std::move(sequenced));
761 765
762 if (sequenced.shutdown_behavior == BLOCK_SHUTDOWN) 766 if (shutdown_behavior == BLOCK_SHUTDOWN)
763 blocking_shutdown_pending_task_count_++; 767 blocking_shutdown_pending_task_count_++;
764 768
765 create_thread_id = PrepareToStartAdditionalThreadIfHelpful(); 769 create_thread_id = PrepareToStartAdditionalThreadIfHelpful();
766 } 770 }
767 } 771 }
768 772
769 // Use != REDIRECTED_TO_TASK_SCHEDULER instead of == USE_WORKER_POOL to ensure 773 // Use != REDIRECTED_TO_TASK_SCHEDULER instead of == USE_WORKER_POOL to ensure
770 // correct behavior if a task is posted to a SequencedWorkerPool before 774 // correct behavior if a task is posted to a SequencedWorkerPool before
771 // Enable(WithRedirectionToTaskScheduler)ForProcess() in a non-DCHECK build. 775 // Enable(WithRedirectionToTaskScheduler)ForProcess() in a non-DCHECK build.
772 if (g_all_pools_state != AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) { 776 if (g_all_pools_state != AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) {
(...skipping 16 matching lines...) Expand all
789 } else { 793 } else {
790 DCHECK(sequenced_task_runner_map_.empty()); 794 DCHECK(sequenced_task_runner_map_.empty());
791 } 795 }
792 } 796 }
793 #endif // DCHECK_IS_ON() 797 #endif // DCHECK_IS_ON()
794 798
795 return true; 799 return true;
796 } 800 }
797 801
798 bool SequencedWorkerPool::Inner::PostTaskToTaskScheduler( 802 bool SequencedWorkerPool::Inner::PostTaskToTaskScheduler(
799 const SequencedTask& sequenced, 803 SequencedTask sequenced,
800 const TimeDelta& delay) { 804 const TimeDelta& delay) {
801 DCHECK_EQ(AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER, g_all_pools_state); 805 DCHECK_EQ(AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER, g_all_pools_state);
802 806
803 lock_.AssertAcquired(); 807 lock_.AssertAcquired();
804 808
805 // Confirm that the TaskScheduler's shutdown behaviors use the same 809 // Confirm that the TaskScheduler's shutdown behaviors use the same
806 // underlying values as SequencedWorkerPool. 810 // underlying values as SequencedWorkerPool.
807 static_assert( 811 static_assert(
808 static_cast<int>(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) == 812 static_cast<int>(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) ==
809 static_cast<int>(CONTINUE_ON_SHUTDOWN), 813 static_cast<int>(CONTINUE_ON_SHUTDOWN),
810 "TaskShutdownBehavior and WorkerShutdown enum mismatch for " 814 "TaskShutdownBehavior and WorkerShutdown enum mismatch for "
811 "CONTINUE_ON_SHUTDOWN."); 815 "CONTINUE_ON_SHUTDOWN.");
812 static_assert(static_cast<int>(TaskShutdownBehavior::SKIP_ON_SHUTDOWN) == 816 static_assert(static_cast<int>(TaskShutdownBehavior::SKIP_ON_SHUTDOWN) ==
813 static_cast<int>(SKIP_ON_SHUTDOWN), 817 static_cast<int>(SKIP_ON_SHUTDOWN),
814 "TaskShutdownBehavior and WorkerShutdown enum mismatch for " 818 "TaskShutdownBehavior and WorkerShutdown enum mismatch for "
815 "SKIP_ON_SHUTDOWN."); 819 "SKIP_ON_SHUTDOWN.");
816 static_assert(static_cast<int>(TaskShutdownBehavior::BLOCK_SHUTDOWN) == 820 static_assert(static_cast<int>(TaskShutdownBehavior::BLOCK_SHUTDOWN) ==
817 static_cast<int>(BLOCK_SHUTDOWN), 821 static_cast<int>(BLOCK_SHUTDOWN),
818 "TaskShutdownBehavior and WorkerShutdown enum mismatch for " 822 "TaskShutdownBehavior and WorkerShutdown enum mismatch for "
819 "BLOCK_SHUTDOWN."); 823 "BLOCK_SHUTDOWN.");
820 824
821 const TaskShutdownBehavior task_shutdown_behavior = 825 const TaskShutdownBehavior task_shutdown_behavior =
822 static_cast<TaskShutdownBehavior>(sequenced.shutdown_behavior); 826 static_cast<TaskShutdownBehavior>(sequenced.shutdown_behavior);
823 const TaskTraits traits = TaskTraits() 827 const TaskTraits traits = TaskTraits()
824 .MayBlock() 828 .MayBlock()
825 .WithBaseSyncPrimitives() 829 .WithBaseSyncPrimitives()
826 .WithPriority(task_priority_) 830 .WithPriority(task_priority_)
827 .WithShutdownBehavior(task_shutdown_behavior); 831 .WithShutdownBehavior(task_shutdown_behavior);
828 return GetTaskSchedulerTaskRunner(sequenced.sequence_token_id, traits) 832 return GetTaskSchedulerTaskRunner(sequenced.sequence_token_id, traits)
829 ->PostDelayedTask(sequenced.posted_from, sequenced.task, delay); 833 ->PostDelayedTask(sequenced.posted_from, std::move(sequenced.task),
834 delay);
830 } 835 }
831 836
832 scoped_refptr<TaskRunner> 837 scoped_refptr<TaskRunner>
833 SequencedWorkerPool::Inner::GetTaskSchedulerTaskRunner( 838 SequencedWorkerPool::Inner::GetTaskSchedulerTaskRunner(
834 int sequence_token_id, 839 int sequence_token_id,
835 const TaskTraits& traits) { 840 const TaskTraits& traits) {
836 DCHECK_EQ(AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER, g_all_pools_state); 841 DCHECK_EQ(AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER, g_all_pools_state);
837 842
838 lock_.AssertAcquired(); 843 lock_.AssertAcquired();
839 844
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 // can have side effects (like freeing some objects) and deleting a task 1242 // can have side effects (like freeing some objects) and deleting a task
1238 // that's supposed to run after one that's currently running could cause 1243 // that's supposed to run after one that's currently running could cause
1239 // an obscure crash. 1244 // an obscure crash.
1240 // 1245 //
1241 // We really want to delete these tasks outside the lock in case the 1246 // We really want to delete these tasks outside the lock in case the
1242 // closures are holding refs to objects that want to post work from their 1247 // closures are holding refs to objects that want to post work from their
1243 // destructors (which would deadlock). The closures are internally 1248 // destructors (which would deadlock). The closures are internally
1244 // refcounted, so we just need to keep a copy of them alive until the lock 1249 // refcounted, so we just need to keep a copy of them alive until the lock
1245 // is exited. The calling code can just clear() the vector they passed to 1250 // is exited. The calling code can just clear() the vector they passed to
1246 // us once the lock is exited to make this happen. 1251 // us once the lock is exited to make this happen.
1247 delete_these_outside_lock->push_back(*i); 1252 //
1253 // The const_cast here is safe since the object is erased from
1254 // |pending_tasks_| soon after the move.
1255 delete_these_outside_lock->push_back(
1256 std::move(const_cast<SequencedTask&>(*i)));
1248 pending_tasks_.erase(i++); 1257 pending_tasks_.erase(i++);
1249 continue; 1258 continue;
1250 } 1259 }
1251 1260
1252 if (i->time_to_run > current_time) { 1261 if (i->time_to_run > current_time) {
1253 // The time to run has not come yet. 1262 // The time to run has not come yet.
1254 *wait_time = i->time_to_run - current_time; 1263 *wait_time = i->time_to_run - current_time;
1255 status = GET_WORK_WAIT; 1264 status = GET_WORK_WAIT;
1256 if (cleanup_state_ == CLEANUP_RUNNING) { 1265 if (cleanup_state_ == CLEANUP_RUNNING) {
1257 // Deferred tasks are deleted when cleaning up, see Inner::ThreadLoop. 1266 // Deferred tasks are deleted when cleaning up, see Inner::ThreadLoop.
1258 delete_these_outside_lock->push_back(*i); 1267 // The const_cast here is safe since the object is erased from
1268 // |pending_tasks_| soon after the move.
1269 delete_these_outside_lock->push_back(
1270 std::move(const_cast<SequencedTask&>(*i)));
1259 pending_tasks_.erase(i); 1271 pending_tasks_.erase(i);
1260 } 1272 }
1261 break; 1273 break;
1262 } 1274 }
1263 1275
1264 // Found a runnable task. 1276 // Found a runnable task. The const_cast is safe here since the object is
1265 *task = *i; 1277 // erased from |pending_tasks_| soon after the move.
1278 *task = std::move(const_cast<SequencedTask&>(*i));
1266 pending_tasks_.erase(i); 1279 pending_tasks_.erase(i);
1267 if (task->shutdown_behavior == BLOCK_SHUTDOWN) { 1280 if (task->shutdown_behavior == BLOCK_SHUTDOWN) {
1268 blocking_shutdown_pending_task_count_--; 1281 blocking_shutdown_pending_task_count_--;
1269 } 1282 }
1270 1283
1271 status = GET_WORK_FOUND; 1284 status = GET_WORK_FOUND;
1272 break; 1285 break;
1273 } 1286 }
1274 1287
1275 return status; 1288 return status;
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
1528 } 1541 }
1529 1542
1530 scoped_refptr<TaskRunner> 1543 scoped_refptr<TaskRunner>
1531 SequencedWorkerPool::GetTaskRunnerWithShutdownBehavior( 1544 SequencedWorkerPool::GetTaskRunnerWithShutdownBehavior(
1532 WorkerShutdown shutdown_behavior) { 1545 WorkerShutdown shutdown_behavior) {
1533 return new SequencedWorkerPoolTaskRunner(this, shutdown_behavior); 1546 return new SequencedWorkerPoolTaskRunner(this, shutdown_behavior);
1534 } 1547 }
1535 1548
1536 bool SequencedWorkerPool::PostWorkerTask( 1549 bool SequencedWorkerPool::PostWorkerTask(
1537 const tracked_objects::Location& from_here, 1550 const tracked_objects::Location& from_here,
1538 Closure task) { 1551 OnceClosure task) {
1539 return inner_->PostTask(NULL, SequenceToken(), BLOCK_SHUTDOWN, from_here, 1552 return inner_->PostTask(NULL, SequenceToken(), BLOCK_SHUTDOWN, from_here,
1540 std::move(task), TimeDelta()); 1553 std::move(task), TimeDelta());
1541 } 1554 }
1542 1555
1543 bool SequencedWorkerPool::PostDelayedWorkerTask( 1556 bool SequencedWorkerPool::PostDelayedWorkerTask(
1544 const tracked_objects::Location& from_here, 1557 const tracked_objects::Location& from_here,
1545 Closure task, 1558 OnceClosure task,
1546 TimeDelta delay) { 1559 TimeDelta delay) {
1547 WorkerShutdown shutdown_behavior = 1560 WorkerShutdown shutdown_behavior =
1548 delay.is_zero() ? BLOCK_SHUTDOWN : SKIP_ON_SHUTDOWN; 1561 delay.is_zero() ? BLOCK_SHUTDOWN : SKIP_ON_SHUTDOWN;
1549 return inner_->PostTask(NULL, SequenceToken(), shutdown_behavior, from_here, 1562 return inner_->PostTask(NULL, SequenceToken(), shutdown_behavior, from_here,
1550 std::move(task), delay); 1563 std::move(task), delay);
1551 } 1564 }
1552 1565
1553 bool SequencedWorkerPool::PostWorkerTaskWithShutdownBehavior( 1566 bool SequencedWorkerPool::PostWorkerTaskWithShutdownBehavior(
1554 const tracked_objects::Location& from_here, 1567 const tracked_objects::Location& from_here,
1555 Closure task, 1568 OnceClosure task,
1556 WorkerShutdown shutdown_behavior) { 1569 WorkerShutdown shutdown_behavior) {
1557 return inner_->PostTask(NULL, SequenceToken(), shutdown_behavior, from_here, 1570 return inner_->PostTask(NULL, SequenceToken(), shutdown_behavior, from_here,
1558 std::move(task), TimeDelta()); 1571 std::move(task), TimeDelta());
1559 } 1572 }
1560 1573
1561 bool SequencedWorkerPool::PostSequencedWorkerTask( 1574 bool SequencedWorkerPool::PostSequencedWorkerTask(
1562 SequenceToken sequence_token, 1575 SequenceToken sequence_token,
1563 const tracked_objects::Location& from_here, 1576 const tracked_objects::Location& from_here,
1564 Closure task) { 1577 OnceClosure task) {
1565 return inner_->PostTask(NULL, sequence_token, BLOCK_SHUTDOWN, from_here, 1578 return inner_->PostTask(NULL, sequence_token, BLOCK_SHUTDOWN, from_here,
1566 std::move(task), TimeDelta()); 1579 std::move(task), TimeDelta());
1567 } 1580 }
1568 1581
1569 bool SequencedWorkerPool::PostDelayedSequencedWorkerTask( 1582 bool SequencedWorkerPool::PostDelayedSequencedWorkerTask(
1570 SequenceToken sequence_token, 1583 SequenceToken sequence_token,
1571 const tracked_objects::Location& from_here, 1584 const tracked_objects::Location& from_here,
1572 Closure task, 1585 OnceClosure task,
1573 TimeDelta delay) { 1586 TimeDelta delay) {
1574 WorkerShutdown shutdown_behavior = 1587 WorkerShutdown shutdown_behavior =
1575 delay.is_zero() ? BLOCK_SHUTDOWN : SKIP_ON_SHUTDOWN; 1588 delay.is_zero() ? BLOCK_SHUTDOWN : SKIP_ON_SHUTDOWN;
1576 return inner_->PostTask(NULL, sequence_token, shutdown_behavior, from_here, 1589 return inner_->PostTask(NULL, sequence_token, shutdown_behavior, from_here,
1577 std::move(task), delay); 1590 std::move(task), delay);
1578 } 1591 }
1579 1592
1580 bool SequencedWorkerPool::PostNamedSequencedWorkerTask( 1593 bool SequencedWorkerPool::PostNamedSequencedWorkerTask(
1581 const std::string& token_name, 1594 const std::string& token_name,
1582 const tracked_objects::Location& from_here, 1595 const tracked_objects::Location& from_here,
1583 Closure task) { 1596 OnceClosure task) {
1584 DCHECK(!token_name.empty()); 1597 DCHECK(!token_name.empty());
1585 return inner_->PostTask(&token_name, SequenceToken(), BLOCK_SHUTDOWN, 1598 return inner_->PostTask(&token_name, SequenceToken(), BLOCK_SHUTDOWN,
1586 from_here, std::move(task), TimeDelta()); 1599 from_here, std::move(task), TimeDelta());
1587 } 1600 }
1588 1601
1589 bool SequencedWorkerPool::PostSequencedWorkerTaskWithShutdownBehavior( 1602 bool SequencedWorkerPool::PostSequencedWorkerTaskWithShutdownBehavior(
1590 SequenceToken sequence_token, 1603 SequenceToken sequence_token,
1591 const tracked_objects::Location& from_here, 1604 const tracked_objects::Location& from_here,
1592 Closure task, 1605 OnceClosure task,
1593 WorkerShutdown shutdown_behavior) { 1606 WorkerShutdown shutdown_behavior) {
1594 return inner_->PostTask(NULL, sequence_token, shutdown_behavior, from_here, 1607 return inner_->PostTask(NULL, sequence_token, shutdown_behavior, from_here,
1595 std::move(task), TimeDelta()); 1608 std::move(task), TimeDelta());
1596 } 1609 }
1597 1610
1598 bool SequencedWorkerPool::PostDelayedTask( 1611 bool SequencedWorkerPool::PostDelayedTask(
1599 const tracked_objects::Location& from_here, 1612 const tracked_objects::Location& from_here,
1600 Closure task, 1613 OnceClosure task,
1601 TimeDelta delay) { 1614 TimeDelta delay) {
1602 return PostDelayedWorkerTask(from_here, std::move(task), delay); 1615 return PostDelayedWorkerTask(from_here, std::move(task), delay);
1603 } 1616 }
1604 1617
1605 bool SequencedWorkerPool::RunsTasksOnCurrentThread() const { 1618 bool SequencedWorkerPool::RunsTasksOnCurrentThread() const {
1606 return inner_->RunsTasksOnCurrentThread(); 1619 return inner_->RunsTasksOnCurrentThread();
1607 } 1620 }
1608 1621
1609 void SequencedWorkerPool::FlushForTesting() { 1622 void SequencedWorkerPool::FlushForTesting() {
1610 DCHECK(!RunsTasksOnCurrentThread()); 1623 DCHECK(!RunsTasksOnCurrentThread());
(...skipping 18 matching lines...) Expand all
1629 bool SequencedWorkerPool::IsShutdownInProgress() { 1642 bool SequencedWorkerPool::IsShutdownInProgress() {
1630 return inner_->IsShutdownInProgress(); 1643 return inner_->IsShutdownInProgress();
1631 } 1644 }
1632 1645
1633 bool SequencedWorkerPool::IsRunningSequenceOnCurrentThread( 1646 bool SequencedWorkerPool::IsRunningSequenceOnCurrentThread(
1634 SequenceToken sequence_token) const { 1647 SequenceToken sequence_token) const {
1635 return inner_->IsRunningSequenceOnCurrentThread(sequence_token); 1648 return inner_->IsRunningSequenceOnCurrentThread(sequence_token);
1636 } 1649 }
1637 1650
1638 } // namespace base 1651 } // namespace base
OLDNEW
« no previous file with comments | « base/threading/sequenced_worker_pool.h ('k') | base/threading/worker_pool.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698