| 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 <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <list> | 9 #include <list> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 sequence_task_number(0), | 82 sequence_task_number(0), |
| 83 shutdown_behavior(SequencedWorkerPool::BLOCK_SHUTDOWN) {} | 83 shutdown_behavior(SequencedWorkerPool::BLOCK_SHUTDOWN) {} |
| 84 | 84 |
| 85 explicit SequencedTask(const tracked_objects::Location& from_here) | 85 explicit SequencedTask(const tracked_objects::Location& from_here) |
| 86 : base::TrackingInfo(from_here, TimeTicks()), | 86 : base::TrackingInfo(from_here, TimeTicks()), |
| 87 sequence_token_id(0), | 87 sequence_token_id(0), |
| 88 trace_id(0), | 88 trace_id(0), |
| 89 sequence_task_number(0), | 89 sequence_task_number(0), |
| 90 shutdown_behavior(SequencedWorkerPool::BLOCK_SHUTDOWN) {} | 90 shutdown_behavior(SequencedWorkerPool::BLOCK_SHUTDOWN) {} |
| 91 | 91 |
| 92 SequencedTask(SequencedTask&&) = default; |
| 93 SequencedTask& operator=(SequencedTask&&) = default; |
| 94 |
| 92 ~SequencedTask() {} | 95 ~SequencedTask() {} |
| 93 | 96 |
| 94 int sequence_token_id; | 97 int sequence_token_id; |
| 95 int trace_id; | 98 int trace_id; |
| 96 int64_t sequence_task_number; | 99 int64_t sequence_task_number; |
| 97 SequencedWorkerPool::WorkerShutdown shutdown_behavior; | 100 SequencedWorkerPool::WorkerShutdown shutdown_behavior; |
| 98 tracked_objects::Location posted_from; | 101 tracked_objects::Location posted_from; |
| 99 Closure task; | 102 mutable OnceClosure task; |
| 100 | 103 |
| 101 // Non-delayed tasks and delayed tasks are managed together by time-to-run | 104 // Non-delayed tasks and delayed tasks are managed together by time-to-run |
| 102 // order. We calculate the time by adding the posted time and the given delay. | 105 // order. We calculate the time by adding the posted time and the given delay. |
| 103 TimeTicks time_to_run; | 106 TimeTicks time_to_run; |
| 104 }; | 107 }; |
| 105 | 108 |
| 106 struct SequencedTaskLessThan { | 109 struct SequencedTaskLessThan { |
| 107 public: | 110 public: |
| 108 bool operator()(const SequencedTask& lhs, const SequencedTask& rhs) const { | 111 bool operator()(const SequencedTask& lhs, const SequencedTask& rhs) const { |
| 109 if (lhs.time_to_run < rhs.time_to_run) | 112 if (lhs.time_to_run < rhs.time_to_run) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 123 // | 126 // |
| 124 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). | 127 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). |
| 125 class SequencedWorkerPoolTaskRunner : public TaskRunner { | 128 class SequencedWorkerPoolTaskRunner : public TaskRunner { |
| 126 public: | 129 public: |
| 127 SequencedWorkerPoolTaskRunner( | 130 SequencedWorkerPoolTaskRunner( |
| 128 scoped_refptr<SequencedWorkerPool> pool, | 131 scoped_refptr<SequencedWorkerPool> pool, |
| 129 SequencedWorkerPool::WorkerShutdown shutdown_behavior); | 132 SequencedWorkerPool::WorkerShutdown shutdown_behavior); |
| 130 | 133 |
| 131 // TaskRunner implementation | 134 // TaskRunner implementation |
| 132 bool PostDelayedTask(const tracked_objects::Location& from_here, | 135 bool PostDelayedTask(const tracked_objects::Location& from_here, |
| 133 const Closure& task, | 136 OnceClosure task, |
| 134 TimeDelta delay) override; | 137 TimeDelta delay) override; |
| 135 bool RunsTasksOnCurrentThread() const override; | 138 bool RunsTasksOnCurrentThread() const override; |
| 136 | 139 |
| 137 private: | 140 private: |
| 138 ~SequencedWorkerPoolTaskRunner() override; | 141 ~SequencedWorkerPoolTaskRunner() override; |
| 139 | 142 |
| 140 const scoped_refptr<SequencedWorkerPool> pool_; | 143 const scoped_refptr<SequencedWorkerPool> pool_; |
| 141 | 144 |
| 142 const SequencedWorkerPool::WorkerShutdown shutdown_behavior_; | 145 const SequencedWorkerPool::WorkerShutdown shutdown_behavior_; |
| 143 | 146 |
| 144 DISALLOW_COPY_AND_ASSIGN(SequencedWorkerPoolTaskRunner); | 147 DISALLOW_COPY_AND_ASSIGN(SequencedWorkerPoolTaskRunner); |
| 145 }; | 148 }; |
| 146 | 149 |
| 147 SequencedWorkerPoolTaskRunner::SequencedWorkerPoolTaskRunner( | 150 SequencedWorkerPoolTaskRunner::SequencedWorkerPoolTaskRunner( |
| 148 scoped_refptr<SequencedWorkerPool> pool, | 151 scoped_refptr<SequencedWorkerPool> pool, |
| 149 SequencedWorkerPool::WorkerShutdown shutdown_behavior) | 152 SequencedWorkerPool::WorkerShutdown shutdown_behavior) |
| 150 : pool_(std::move(pool)), shutdown_behavior_(shutdown_behavior) {} | 153 : pool_(std::move(pool)), shutdown_behavior_(shutdown_behavior) {} |
| 151 | 154 |
| 152 SequencedWorkerPoolTaskRunner::~SequencedWorkerPoolTaskRunner() { | 155 SequencedWorkerPoolTaskRunner::~SequencedWorkerPoolTaskRunner() { |
| 153 } | 156 } |
| 154 | 157 |
| 155 bool SequencedWorkerPoolTaskRunner::PostDelayedTask( | 158 bool SequencedWorkerPoolTaskRunner::PostDelayedTask( |
| 156 const tracked_objects::Location& from_here, | 159 const tracked_objects::Location& from_here, |
| 157 const Closure& task, | 160 OnceClosure task, |
| 158 TimeDelta delay) { | 161 TimeDelta delay) { |
| 159 if (delay.is_zero()) { | 162 if (delay.is_zero()) { |
| 160 return pool_->PostWorkerTaskWithShutdownBehavior( | 163 return pool_->PostWorkerTaskWithShutdownBehavior(from_here, std::move(task), |
| 161 from_here, task, shutdown_behavior_); | 164 shutdown_behavior_); |
| 162 } | 165 } |
| 163 return pool_->PostDelayedWorkerTask(from_here, task, delay); | 166 return pool_->PostDelayedWorkerTask(from_here, std::move(task), delay); |
| 164 } | 167 } |
| 165 | 168 |
| 166 bool SequencedWorkerPoolTaskRunner::RunsTasksOnCurrentThread() const { | 169 bool SequencedWorkerPoolTaskRunner::RunsTasksOnCurrentThread() const { |
| 167 return pool_->RunsTasksOnCurrentThread(); | 170 return pool_->RunsTasksOnCurrentThread(); |
| 168 } | 171 } |
| 169 | 172 |
| 170 // SequencedWorkerPoolSequencedTaskRunner ------------------------------------ | 173 // SequencedWorkerPoolSequencedTaskRunner ------------------------------------ |
| 171 // A SequencedTaskRunner which posts tasks to a SequencedWorkerPool with a | 174 // A SequencedTaskRunner which posts tasks to a SequencedWorkerPool with a |
| 172 // fixed sequence token. | 175 // fixed sequence token. |
| 173 // | 176 // |
| 174 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). | 177 // Note that this class is RefCountedThreadSafe (inherited from TaskRunner). |
| 175 class SequencedWorkerPoolSequencedTaskRunner : public SequencedTaskRunner { | 178 class SequencedWorkerPoolSequencedTaskRunner : public SequencedTaskRunner { |
| 176 public: | 179 public: |
| 177 SequencedWorkerPoolSequencedTaskRunner( | 180 SequencedWorkerPoolSequencedTaskRunner( |
| 178 scoped_refptr<SequencedWorkerPool> pool, | 181 scoped_refptr<SequencedWorkerPool> pool, |
| 179 SequencedWorkerPool::SequenceToken token, | 182 SequencedWorkerPool::SequenceToken token, |
| 180 SequencedWorkerPool::WorkerShutdown shutdown_behavior); | 183 SequencedWorkerPool::WorkerShutdown shutdown_behavior); |
| 181 | 184 |
| 182 // TaskRunner implementation | 185 // TaskRunner implementation |
| 183 bool PostDelayedTask(const tracked_objects::Location& from_here, | 186 bool PostDelayedTask(const tracked_objects::Location& from_here, |
| 184 const Closure& task, | 187 OnceClosure task, |
| 185 TimeDelta delay) override; | 188 TimeDelta delay) override; |
| 186 bool RunsTasksOnCurrentThread() const override; | 189 bool RunsTasksOnCurrentThread() const override; |
| 187 | 190 |
| 188 // SequencedTaskRunner implementation | 191 // SequencedTaskRunner implementation |
| 189 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, | 192 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, |
| 190 const Closure& task, | 193 OnceClosure task, |
| 191 TimeDelta delay) override; | 194 TimeDelta delay) override; |
| 192 | 195 |
| 193 private: | 196 private: |
| 194 ~SequencedWorkerPoolSequencedTaskRunner() override; | 197 ~SequencedWorkerPoolSequencedTaskRunner() override; |
| 195 | 198 |
| 196 const scoped_refptr<SequencedWorkerPool> pool_; | 199 const scoped_refptr<SequencedWorkerPool> pool_; |
| 197 | 200 |
| 198 const SequencedWorkerPool::SequenceToken token_; | 201 const SequencedWorkerPool::SequenceToken token_; |
| 199 | 202 |
| 200 const SequencedWorkerPool::WorkerShutdown shutdown_behavior_; | 203 const SequencedWorkerPool::WorkerShutdown shutdown_behavior_; |
| 201 | 204 |
| 202 DISALLOW_COPY_AND_ASSIGN(SequencedWorkerPoolSequencedTaskRunner); | 205 DISALLOW_COPY_AND_ASSIGN(SequencedWorkerPoolSequencedTaskRunner); |
| 203 }; | 206 }; |
| 204 | 207 |
| 205 SequencedWorkerPoolSequencedTaskRunner::SequencedWorkerPoolSequencedTaskRunner( | 208 SequencedWorkerPoolSequencedTaskRunner::SequencedWorkerPoolSequencedTaskRunner( |
| 206 scoped_refptr<SequencedWorkerPool> pool, | 209 scoped_refptr<SequencedWorkerPool> pool, |
| 207 SequencedWorkerPool::SequenceToken token, | 210 SequencedWorkerPool::SequenceToken token, |
| 208 SequencedWorkerPool::WorkerShutdown shutdown_behavior) | 211 SequencedWorkerPool::WorkerShutdown shutdown_behavior) |
| 209 : pool_(std::move(pool)), | 212 : pool_(std::move(pool)), |
| 210 token_(token), | 213 token_(token), |
| 211 shutdown_behavior_(shutdown_behavior) {} | 214 shutdown_behavior_(shutdown_behavior) {} |
| 212 | 215 |
| 213 SequencedWorkerPoolSequencedTaskRunner:: | 216 SequencedWorkerPoolSequencedTaskRunner:: |
| 214 ~SequencedWorkerPoolSequencedTaskRunner() { | 217 ~SequencedWorkerPoolSequencedTaskRunner() { |
| 215 } | 218 } |
| 216 | 219 |
| 217 bool SequencedWorkerPoolSequencedTaskRunner::PostDelayedTask( | 220 bool SequencedWorkerPoolSequencedTaskRunner::PostDelayedTask( |
| 218 const tracked_objects::Location& from_here, | 221 const tracked_objects::Location& from_here, |
| 219 const Closure& task, | 222 OnceClosure task, |
| 220 TimeDelta delay) { | 223 TimeDelta delay) { |
| 221 if (delay.is_zero()) { | 224 if (delay.is_zero()) { |
| 222 return pool_->PostSequencedWorkerTaskWithShutdownBehavior( | 225 return pool_->PostSequencedWorkerTaskWithShutdownBehavior( |
| 223 token_, from_here, task, shutdown_behavior_); | 226 token_, from_here, std::move(task), shutdown_behavior_); |
| 224 } | 227 } |
| 225 return pool_->PostDelayedSequencedWorkerTask(token_, from_here, task, delay); | 228 return pool_->PostDelayedSequencedWorkerTask(token_, from_here, |
| 229 std::move(task), delay); |
| 226 } | 230 } |
| 227 | 231 |
| 228 bool SequencedWorkerPoolSequencedTaskRunner::RunsTasksOnCurrentThread() const { | 232 bool SequencedWorkerPoolSequencedTaskRunner::RunsTasksOnCurrentThread() const { |
| 229 return pool_->IsRunningSequenceOnCurrentThread(token_); | 233 return pool_->IsRunningSequenceOnCurrentThread(token_); |
| 230 } | 234 } |
| 231 | 235 |
| 232 bool SequencedWorkerPoolSequencedTaskRunner::PostNonNestableDelayedTask( | 236 bool SequencedWorkerPoolSequencedTaskRunner::PostNonNestableDelayedTask( |
| 233 const tracked_objects::Location& from_here, | 237 const tracked_objects::Location& from_here, |
| 234 const Closure& task, | 238 OnceClosure task, |
| 235 TimeDelta delay) { | 239 TimeDelta delay) { |
| 236 // There's no way to run nested tasks, so simply forward to | 240 // There's no way to run nested tasks, so simply forward to |
| 237 // PostDelayedTask. | 241 // PostDelayedTask. |
| 238 return PostDelayedTask(from_here, task, delay); | 242 return PostDelayedTask(from_here, std::move(task), delay); |
| 239 } | 243 } |
| 240 | 244 |
| 241 // Create a process-wide unique ID to represent this task in trace events. This | 245 // Create a process-wide unique ID to represent this task in trace events. This |
| 242 // will be mangled with a Process ID hash to reduce the likelyhood of colliding | 246 // will be mangled with a Process ID hash to reduce the likelyhood of colliding |
| 243 // with MessageLoop pointers on other processes. | 247 // with MessageLoop pointers on other processes. |
| 244 uint64_t GetTaskTraceID(const SequencedTask& task, void* pool) { | 248 uint64_t GetTaskTraceID(const SequencedTask& task, void* pool) { |
| 245 return (static_cast<uint64_t>(task.trace_id) << 32) | | 249 return (static_cast<uint64_t>(task.trace_id) << 32) | |
| 246 static_cast<uint64_t>(reinterpret_cast<intptr_t>(pool)); | 250 static_cast<uint64_t>(reinterpret_cast<intptr_t>(pool)); |
| 247 } | 251 } |
| 248 | 252 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 | 341 |
| 338 SequenceToken GetNamedSequenceToken(const std::string& name); | 342 SequenceToken GetNamedSequenceToken(const std::string& name); |
| 339 | 343 |
| 340 // This function accepts a name and an ID. If the name is null, the | 344 // This function accepts a name and an ID. If the name is null, the |
| 341 // token ID is used. This allows us to implement the optional name lookup | 345 // token ID is used. This allows us to implement the optional name lookup |
| 342 // from a single function without having to enter the lock a separate time. | 346 // from a single function without having to enter the lock a separate time. |
| 343 bool PostTask(const std::string* optional_token_name, | 347 bool PostTask(const std::string* optional_token_name, |
| 344 SequenceToken sequence_token, | 348 SequenceToken sequence_token, |
| 345 WorkerShutdown shutdown_behavior, | 349 WorkerShutdown shutdown_behavior, |
| 346 const tracked_objects::Location& from_here, | 350 const tracked_objects::Location& from_here, |
| 347 const Closure& task, | 351 OnceClosure task, |
| 348 TimeDelta delay); | 352 TimeDelta delay); |
| 349 | 353 |
| 350 bool RunsTasksOnCurrentThread() const; | 354 bool RunsTasksOnCurrentThread() const; |
| 351 | 355 |
| 352 bool IsRunningSequenceOnCurrentThread(SequenceToken sequence_token) const; | 356 bool IsRunningSequenceOnCurrentThread(SequenceToken sequence_token) const; |
| 353 | 357 |
| 354 void CleanupForTesting(); | 358 void CleanupForTesting(); |
| 355 | 359 |
| 356 void SignalHasWorkForTesting(); | 360 void SignalHasWorkForTesting(); |
| 357 | 361 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 374 enum CleanupState { | 378 enum CleanupState { |
| 375 CLEANUP_REQUESTED, | 379 CLEANUP_REQUESTED, |
| 376 CLEANUP_STARTING, | 380 CLEANUP_STARTING, |
| 377 CLEANUP_RUNNING, | 381 CLEANUP_RUNNING, |
| 378 CLEANUP_FINISHING, | 382 CLEANUP_FINISHING, |
| 379 CLEANUP_DONE, | 383 CLEANUP_DONE, |
| 380 }; | 384 }; |
| 381 | 385 |
| 382 // Helper used by PostTask() to complete the work when redirection is on. | 386 // Helper used by PostTask() to complete the work when redirection is on. |
| 383 // Coalesce upon resolution of http://crbug.com/622400. | 387 // Coalesce upon resolution of http://crbug.com/622400. |
| 384 void PostTaskToTaskScheduler(const SequencedTask& sequenced); | 388 void PostTaskToTaskScheduler(SequencedTask sequenced); |
| 385 | 389 |
| 386 // Called from within the lock, this converts the given token name into a | 390 // Called from within the lock, this converts the given token name into a |
| 387 // token ID, creating a new one if necessary. | 391 // token ID, creating a new one if necessary. |
| 388 int LockedGetNamedTokenID(const std::string& name); | 392 int LockedGetNamedTokenID(const std::string& name); |
| 389 | 393 |
| 390 // Called from within the lock, this returns the next sequence task number. | 394 // Called from within the lock, this returns the next sequence task number. |
| 391 int64_t LockedGetNextSequenceTaskNumber(); | 395 int64_t LockedGetNextSequenceTaskNumber(); |
| 392 | 396 |
| 393 // Gets new task. There are 3 cases depending on the return value: | 397 // Gets new task. There are 3 cases depending on the return value: |
| 394 // | 398 // |
| 395 // 1) If the return value is |GET_WORK_FOUND|, |task| is filled in and should | 399 // 1) If the return value is |GET_WORK_FOUND|, |task| is filled in and should |
| 396 // be run immediately. | 400 // be run immediately. |
| 397 // 2) If the return value is |GET_WORK_NOT_FOUND|, there are no tasks to run, | 401 // 2) If the return value is |GET_WORK_NOT_FOUND|, there are no tasks to run, |
| 398 // and |task| is not filled in. In this case, the caller should wait until | 402 // and |task| is not filled in. In this case, the caller should wait until |
| 399 // a task is posted. | 403 // a task is posted. |
| 400 // 3) If the return value is |GET_WORK_WAIT|, there are no tasks to run | 404 // 3) If the return value is |GET_WORK_WAIT|, there are no tasks to run |
| 401 // immediately, and |task| is not filled in. Likewise, |wait_time| is | 405 // immediately, and |task| is not filled in. Likewise, |wait_time| is |
| 402 // filled in the time to wait until the next task to run. In this case, the | 406 // filled in the time to wait until the next task to run. In this case, the |
| 403 // caller should wait the time. | 407 // caller should wait the time. |
| 404 // | 408 // |
| 405 // In any case, the calling code should clear the given | 409 // In any case, the calling code should clear the given |
| 406 // delete_these_outside_lock vector the next time the lock is released. | 410 // delete_these_outside_lock vector the next time the lock is released. |
| 407 // See the implementation for a more detailed description. | 411 // See the implementation for a more detailed description. |
| 408 GetWorkStatus GetWork(SequencedTask* task, | 412 GetWorkStatus GetWork(SequencedTask* task, |
| 409 TimeDelta* wait_time, | 413 TimeDelta* wait_time, |
| 410 std::vector<Closure>* delete_these_outside_lock); | 414 std::vector<OnceClosure>* delete_these_outside_lock); |
| 411 | 415 |
| 412 void HandleCleanup(); | 416 void HandleCleanup(); |
| 413 | 417 |
| 414 // Peforms init and cleanup around running the given task. WillRun... | 418 // Peforms init and cleanup around running the given task. WillRun... |
| 415 // returns the value from PrepareToStartAdditionalThreadIfNecessary. | 419 // returns the value from PrepareToStartAdditionalThreadIfNecessary. |
| 416 // The calling code should call FinishStartingAdditionalThread once the | 420 // The calling code should call FinishStartingAdditionalThread once the |
| 417 // lock is released if the return values is nonzero. | 421 // lock is released if the return values is nonzero. |
| 418 int WillRunWorkerTask(const SequencedTask& task); | 422 int WillRunWorkerTask(const SequencedTask& task); |
| 419 void DidRunWorkerTask(const SequencedTask& task); | 423 void DidRunWorkerTask(const SequencedTask& task); |
| 420 | 424 |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 SequencedWorkerPool::Inner::GetNamedSequenceToken(const std::string& name) { | 663 SequencedWorkerPool::Inner::GetNamedSequenceToken(const std::string& name) { |
| 660 AutoLock lock(lock_); | 664 AutoLock lock(lock_); |
| 661 return SequenceToken(LockedGetNamedTokenID(name)); | 665 return SequenceToken(LockedGetNamedTokenID(name)); |
| 662 } | 666 } |
| 663 | 667 |
| 664 bool SequencedWorkerPool::Inner::PostTask( | 668 bool SequencedWorkerPool::Inner::PostTask( |
| 665 const std::string* optional_token_name, | 669 const std::string* optional_token_name, |
| 666 SequenceToken sequence_token, | 670 SequenceToken sequence_token, |
| 667 WorkerShutdown shutdown_behavior, | 671 WorkerShutdown shutdown_behavior, |
| 668 const tracked_objects::Location& from_here, | 672 const tracked_objects::Location& from_here, |
| 669 const Closure& task, | 673 OnceClosure task, |
| 670 TimeDelta delay) { | 674 TimeDelta delay) { |
| 671 DCHECK(delay.is_zero() || shutdown_behavior == SKIP_ON_SHUTDOWN); | 675 DCHECK(delay.is_zero() || shutdown_behavior == SKIP_ON_SHUTDOWN); |
| 672 SequencedTask sequenced(from_here); | 676 SequencedTask sequenced(from_here); |
| 673 sequenced.sequence_token_id = sequence_token.id_; | 677 sequenced.sequence_token_id = sequence_token.id_; |
| 674 sequenced.shutdown_behavior = shutdown_behavior; | 678 sequenced.shutdown_behavior = shutdown_behavior; |
| 675 sequenced.posted_from = from_here; | 679 sequenced.posted_from = from_here; |
| 676 sequenced.task = | 680 sequenced.task = shutdown_behavior == BLOCK_SHUTDOWN |
| 677 shutdown_behavior == BLOCK_SHUTDOWN ? | 681 ? base::MakeCriticalClosure(std::move(task)) |
| 678 base::MakeCriticalClosure(task) : task; | 682 : std::move(task); |
| 679 sequenced.time_to_run = TimeTicks::Now() + delay; | 683 sequenced.time_to_run = TimeTicks::Now() + delay; |
| 680 | 684 |
| 681 int create_thread_id = 0; | 685 int create_thread_id = 0; |
| 682 { | 686 { |
| 683 AutoLock lock(lock_); | 687 AutoLock lock(lock_); |
| 684 | 688 |
| 685 if (shutdown_called_) { | 689 if (shutdown_called_) { |
| 686 // Don't allow a new task to be posted if it doesn't block shutdown. | 690 // Don't allow a new task to be posted if it doesn't block shutdown. |
| 687 if (shutdown_behavior != BLOCK_SHUTDOWN) | 691 if (shutdown_behavior != BLOCK_SHUTDOWN) |
| 688 return false; | 692 return false; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 712 TRACE_EVENT_FLAG_FLOW_OUT); | 716 TRACE_EVENT_FLAG_FLOW_OUT); |
| 713 | 717 |
| 714 sequenced.sequence_task_number = LockedGetNextSequenceTaskNumber(); | 718 sequenced.sequence_task_number = LockedGetNextSequenceTaskNumber(); |
| 715 | 719 |
| 716 // Now that we have the lock, apply the named token rules. | 720 // Now that we have the lock, apply the named token rules. |
| 717 if (optional_token_name) | 721 if (optional_token_name) |
| 718 sequenced.sequence_token_id = LockedGetNamedTokenID(*optional_token_name); | 722 sequenced.sequence_token_id = LockedGetNamedTokenID(*optional_token_name); |
| 719 | 723 |
| 720 if (subtle::NoBarrier_Load(&g_all_pools_state) == | 724 if (subtle::NoBarrier_Load(&g_all_pools_state) == |
| 721 AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) { | 725 AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) { |
| 722 PostTaskToTaskScheduler(sequenced); | 726 PostTaskToTaskScheduler(std::move(sequenced)); |
| 723 } else { | 727 } else { |
| 724 pending_tasks_.insert(sequenced); | 728 SequencedWorkerPool::WorkerShutdown shutdown_behavior = |
| 729 sequenced.shutdown_behavior; |
| 730 pending_tasks_.insert(std::move(sequenced)); |
| 725 | 731 |
| 726 if (sequenced.shutdown_behavior == BLOCK_SHUTDOWN) | 732 if (shutdown_behavior == BLOCK_SHUTDOWN) |
| 727 blocking_shutdown_pending_task_count_++; | 733 blocking_shutdown_pending_task_count_++; |
| 728 | 734 |
| 729 create_thread_id = PrepareToStartAdditionalThreadIfHelpful(); | 735 create_thread_id = PrepareToStartAdditionalThreadIfHelpful(); |
| 730 } | 736 } |
| 731 } | 737 } |
| 732 | 738 |
| 733 if (subtle::NoBarrier_Load(&g_all_pools_state) != | 739 if (subtle::NoBarrier_Load(&g_all_pools_state) != |
| 734 AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) { | 740 AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) { |
| 735 // Actually start the additional thread or signal an existing one outside | 741 // Actually start the additional thread or signal an existing one outside |
| 736 // the lock. | 742 // the lock. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 752 } else { | 758 } else { |
| 753 DCHECK(sequenced_task_runner_map_.empty()); | 759 DCHECK(sequenced_task_runner_map_.empty()); |
| 754 } | 760 } |
| 755 } | 761 } |
| 756 #endif // DCHECK_IS_ON() | 762 #endif // DCHECK_IS_ON() |
| 757 | 763 |
| 758 return true; | 764 return true; |
| 759 } | 765 } |
| 760 | 766 |
| 761 void SequencedWorkerPool::Inner::PostTaskToTaskScheduler( | 767 void SequencedWorkerPool::Inner::PostTaskToTaskScheduler( |
| 762 const SequencedTask& sequenced) { | 768 SequencedTask sequenced) { |
| 763 DCHECK_EQ(AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER, | 769 DCHECK_EQ(AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER, |
| 764 subtle::NoBarrier_Load(&g_all_pools_state)); | 770 subtle::NoBarrier_Load(&g_all_pools_state)); |
| 765 | 771 |
| 766 lock_.AssertAcquired(); | 772 lock_.AssertAcquired(); |
| 767 | 773 |
| 768 // Confirm that the TaskScheduler's shutdown behaviors use the same | 774 // Confirm that the TaskScheduler's shutdown behaviors use the same |
| 769 // underlying values as SequencedWorkerPool. | 775 // underlying values as SequencedWorkerPool. |
| 770 static_assert( | 776 static_assert( |
| 771 static_cast<int>(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) == | 777 static_cast<int>(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) == |
| 772 static_cast<int>(CONTINUE_ON_SHUTDOWN), | 778 static_cast<int>(CONTINUE_ON_SHUTDOWN), |
| (...skipping 26 matching lines...) Expand all Loading... |
| 799 const ExecutionMode execution_mode = | 805 const ExecutionMode execution_mode = |
| 800 max_threads_ == 1U ? ExecutionMode::SINGLE_THREADED | 806 max_threads_ == 1U ? ExecutionMode::SINGLE_THREADED |
| 801 : ExecutionMode::SEQUENCED; | 807 : ExecutionMode::SEQUENCED; |
| 802 *sequenced_task_runner = | 808 *sequenced_task_runner = |
| 803 CreateTaskRunnerWithTraits(pool_traits, execution_mode); | 809 CreateTaskRunnerWithTraits(pool_traits, execution_mode); |
| 804 } | 810 } |
| 805 } | 811 } |
| 806 | 812 |
| 807 if (sequenced_task_runner) { | 813 if (sequenced_task_runner) { |
| 808 (*sequenced_task_runner) | 814 (*sequenced_task_runner) |
| 809 ->PostTask(sequenced.posted_from, sequenced.task); | 815 ->PostTask(sequenced.posted_from, std::move(sequenced.task)); |
| 810 } else { | 816 } else { |
| 811 // PostTaskWithTraits() posts a task with PARALLEL semantics. There are | 817 // PostTaskWithTraits() posts a task with PARALLEL semantics. There are |
| 812 // however a few pools that use only one thread and therefore can currently | 818 // however a few pools that use only one thread and therefore can currently |
| 813 // legitimatelly assume thread affinity despite using SequencedWorkerPool. | 819 // legitimatelly assume thread affinity despite using SequencedWorkerPool. |
| 814 // Such pools typically only give access to their TaskRunner which will be | 820 // Such pools typically only give access to their TaskRunner which will be |
| 815 // SINGLE_THREADED per nature of the pool having only one thread but this | 821 // SINGLE_THREADED per nature of the pool having only one thread but this |
| 816 // DCHECK ensures no such pools use SequencedWorkerPool::PostTask() | 822 // DCHECK ensures no such pools use SequencedWorkerPool::PostTask() |
| 817 // directly. | 823 // directly. |
| 818 DCHECK_GT(max_threads_, 1U); | 824 DCHECK_GT(max_threads_, 1U); |
| 819 base::PostTaskWithTraits(sequenced.posted_from, pool_traits, | 825 base::PostTaskWithTraits(sequenced.posted_from, pool_traits, |
| 820 sequenced.task); | 826 std::move(sequenced.task)); |
| 821 } | 827 } |
| 822 } | 828 } |
| 823 | 829 |
| 824 bool SequencedWorkerPool::Inner::RunsTasksOnCurrentThread() const { | 830 bool SequencedWorkerPool::Inner::RunsTasksOnCurrentThread() const { |
| 825 AutoLock lock(lock_); | 831 AutoLock lock(lock_); |
| 826 if (subtle::NoBarrier_Load(&g_all_pools_state) == | 832 if (subtle::NoBarrier_Load(&g_all_pools_state) == |
| 827 AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) { | 833 AllPoolsState::REDIRECTED_TO_TASK_SCHEDULER) { |
| 828 if (!runs_tasks_on_verifier_) { | 834 if (!runs_tasks_on_verifier_) { |
| 829 runs_tasks_on_verifier_ = CreateTaskRunnerWithTraits( | 835 runs_tasks_on_verifier_ = CreateTaskRunnerWithTraits( |
| 830 TaskTraits().WithFileIO().WithPriority(task_priority_), | 836 TaskTraits().WithFileIO().WithPriority(task_priority_), |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 947 while (true) { | 953 while (true) { |
| 948 #if defined(OS_MACOSX) | 954 #if defined(OS_MACOSX) |
| 949 base::mac::ScopedNSAutoreleasePool autorelease_pool; | 955 base::mac::ScopedNSAutoreleasePool autorelease_pool; |
| 950 #endif | 956 #endif |
| 951 | 957 |
| 952 HandleCleanup(); | 958 HandleCleanup(); |
| 953 | 959 |
| 954 // See GetWork for what delete_these_outside_lock is doing. | 960 // See GetWork for what delete_these_outside_lock is doing. |
| 955 SequencedTask task; | 961 SequencedTask task; |
| 956 TimeDelta wait_time; | 962 TimeDelta wait_time; |
| 957 std::vector<Closure> delete_these_outside_lock; | 963 std::vector<OnceClosure> delete_these_outside_lock; |
| 958 GetWorkStatus status = | 964 GetWorkStatus status = |
| 959 GetWork(&task, &wait_time, &delete_these_outside_lock); | 965 GetWork(&task, &wait_time, &delete_these_outside_lock); |
| 960 if (status == GET_WORK_FOUND) { | 966 if (status == GET_WORK_FOUND) { |
| 961 TRACE_EVENT_WITH_FLOW2(TRACE_DISABLED_BY_DEFAULT("toplevel.flow"), | 967 TRACE_EVENT_WITH_FLOW2(TRACE_DISABLED_BY_DEFAULT("toplevel.flow"), |
| 962 "SequencedWorkerPool::Inner::ThreadLoop", | 968 "SequencedWorkerPool::Inner::ThreadLoop", |
| 963 TRACE_ID_MANGLE(GetTaskTraceID(task, static_cast<void*>(this))), | 969 TRACE_ID_MANGLE(GetTaskTraceID(task, static_cast<void*>(this))), |
| 964 TRACE_EVENT_FLAG_FLOW_IN, | 970 TRACE_EVENT_FLAG_FLOW_IN, |
| 965 "src_file", task.posted_from.file_name(), | 971 "src_file", task.posted_from.file_name(), |
| 966 "src_func", task.posted_from.function_name()); | 972 "src_func", task.posted_from.function_name()); |
| 967 TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION task_event( | 973 TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION task_event( |
| (...skipping 10 matching lines...) Expand all Loading... |
| 978 | 984 |
| 979 // Complete thread creation outside the lock if necessary. | 985 // Complete thread creation outside the lock if necessary. |
| 980 if (new_thread_id) | 986 if (new_thread_id) |
| 981 FinishStartingAdditionalThread(new_thread_id); | 987 FinishStartingAdditionalThread(new_thread_id); |
| 982 | 988 |
| 983 this_worker->set_running_task_info( | 989 this_worker->set_running_task_info( |
| 984 SequenceToken(task.sequence_token_id), task.shutdown_behavior); | 990 SequenceToken(task.sequence_token_id), task.shutdown_behavior); |
| 985 | 991 |
| 986 tracked_objects::TaskStopwatch stopwatch; | 992 tracked_objects::TaskStopwatch stopwatch; |
| 987 stopwatch.Start(); | 993 stopwatch.Start(); |
| 988 task.task.Run(); | 994 std::move(task.task).Run(); |
| 989 stopwatch.Stop(); | 995 stopwatch.Stop(); |
| 990 | 996 |
| 991 tracked_objects::ThreadData::TallyRunOnNamedThreadIfTracking( | 997 tracked_objects::ThreadData::TallyRunOnNamedThreadIfTracking( |
| 992 task, stopwatch); | 998 task, stopwatch); |
| 993 | 999 |
| 994 // Make sure our task is erased outside the lock for the | 1000 // Make sure our task is erased outside the lock for the |
| 995 // same reason we do this with delete_these_oustide_lock. | 1001 // same reason we do this with delete_these_oustide_lock. |
| 996 // Also, do it before calling reset_running_task_info() so | 1002 // Also, do it before calling reset_running_task_info() so |
| 997 // that sequence-checking from within the task's destructor | 1003 // that sequence-checking from within the task's destructor |
| 998 // still works. | 1004 // still works. |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1130 | 1136 |
| 1131 int64_t SequencedWorkerPool::Inner::LockedGetNextSequenceTaskNumber() { | 1137 int64_t SequencedWorkerPool::Inner::LockedGetNextSequenceTaskNumber() { |
| 1132 lock_.AssertAcquired(); | 1138 lock_.AssertAcquired(); |
| 1133 // We assume that we never create enough tasks to wrap around. | 1139 // We assume that we never create enough tasks to wrap around. |
| 1134 return next_sequence_task_number_++; | 1140 return next_sequence_task_number_++; |
| 1135 } | 1141 } |
| 1136 | 1142 |
| 1137 SequencedWorkerPool::Inner::GetWorkStatus SequencedWorkerPool::Inner::GetWork( | 1143 SequencedWorkerPool::Inner::GetWorkStatus SequencedWorkerPool::Inner::GetWork( |
| 1138 SequencedTask* task, | 1144 SequencedTask* task, |
| 1139 TimeDelta* wait_time, | 1145 TimeDelta* wait_time, |
| 1140 std::vector<Closure>* delete_these_outside_lock) { | 1146 std::vector<OnceClosure>* delete_these_outside_lock) { |
| 1141 DCHECK_EQ(AllPoolsState::WORKER_CREATED, | 1147 DCHECK_EQ(AllPoolsState::WORKER_CREATED, |
| 1142 subtle::NoBarrier_Load(&g_all_pools_state)); | 1148 subtle::NoBarrier_Load(&g_all_pools_state)); |
| 1143 | 1149 |
| 1144 lock_.AssertAcquired(); | 1150 lock_.AssertAcquired(); |
| 1145 | 1151 |
| 1146 // Find the next task with a sequence token that's not currently in use. | 1152 // Find the next task with a sequence token that's not currently in use. |
| 1147 // If the token is in use, that means another thread is running something | 1153 // If the token is in use, that means another thread is running something |
| 1148 // in that sequence, and we can't run it without going out-of-order. | 1154 // in that sequence, and we can't run it without going out-of-order. |
| 1149 // | 1155 // |
| 1150 // This algorithm is simple and fair, but inefficient in some cases. For | 1156 // This algorithm is simple and fair, but inefficient in some cases. For |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1188 // task that's supposed to run after one that's currently running could | 1194 // task that's supposed to run after one that's currently running could |
| 1189 // cause an obscure crash. | 1195 // cause an obscure crash. |
| 1190 // | 1196 // |
| 1191 // We really want to delete these tasks outside the lock in case the | 1197 // We really want to delete these tasks outside the lock in case the |
| 1192 // closures are holding refs to objects that want to post work from | 1198 // closures are holding refs to objects that want to post work from |
| 1193 // their destructorss (which would deadlock). The closures are | 1199 // their destructorss (which would deadlock). The closures are |
| 1194 // internally refcounted, so we just need to keep a copy of them alive | 1200 // internally refcounted, so we just need to keep a copy of them alive |
| 1195 // until the lock is exited. The calling code can just clear() the | 1201 // until the lock is exited. The calling code can just clear() the |
| 1196 // vector they passed to us once the lock is exited to make this | 1202 // vector they passed to us once the lock is exited to make this |
| 1197 // happen. | 1203 // happen. |
| 1198 delete_these_outside_lock->push_back(i->task); | 1204 OnceClosure cb = std::move(i->task); |
| 1205 delete_these_outside_lock->push_back(std::move(cb)); |
| 1199 pending_tasks_.erase(i++); | 1206 pending_tasks_.erase(i++); |
| 1200 continue; | 1207 continue; |
| 1201 } | 1208 } |
| 1202 | 1209 |
| 1203 if (i->time_to_run > current_time) { | 1210 if (i->time_to_run > current_time) { |
| 1204 // The time to run has not come yet. | 1211 // The time to run has not come yet. |
| 1205 *wait_time = i->time_to_run - current_time; | 1212 *wait_time = i->time_to_run - current_time; |
| 1206 status = GET_WORK_WAIT; | 1213 status = GET_WORK_WAIT; |
| 1207 if (cleanup_state_ == CLEANUP_RUNNING) { | 1214 if (cleanup_state_ == CLEANUP_RUNNING) { |
| 1208 // Deferred tasks are deleted when cleaning up, see Inner::ThreadLoop. | 1215 // Deferred tasks are deleted when cleaning up, see Inner::ThreadLoop. |
| 1209 delete_these_outside_lock->push_back(i->task); | 1216 delete_these_outside_lock->push_back(std::move(i->task)); |
| 1210 pending_tasks_.erase(i); | 1217 pending_tasks_.erase(i); |
| 1211 } | 1218 } |
| 1212 break; | 1219 break; |
| 1213 } | 1220 } |
| 1214 | 1221 |
| 1215 // Found a runnable task. | 1222 // Found a runnable task.o |
| 1216 *task = *i; | 1223 *task = std::move(const_cast<SequencedTask&>(*i)); |
| 1217 pending_tasks_.erase(i); | 1224 pending_tasks_.erase(i); |
| 1218 if (task->shutdown_behavior == BLOCK_SHUTDOWN) { | 1225 if (task->shutdown_behavior == BLOCK_SHUTDOWN) { |
| 1219 blocking_shutdown_pending_task_count_--; | 1226 blocking_shutdown_pending_task_count_--; |
| 1220 } | 1227 } |
| 1221 | 1228 |
| 1222 status = GET_WORK_FOUND; | 1229 status = GET_WORK_FOUND; |
| 1223 break; | 1230 break; |
| 1224 } | 1231 } |
| 1225 | 1232 |
| 1226 return status; | 1233 return status; |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1476 } | 1483 } |
| 1477 | 1484 |
| 1478 scoped_refptr<TaskRunner> | 1485 scoped_refptr<TaskRunner> |
| 1479 SequencedWorkerPool::GetTaskRunnerWithShutdownBehavior( | 1486 SequencedWorkerPool::GetTaskRunnerWithShutdownBehavior( |
| 1480 WorkerShutdown shutdown_behavior) { | 1487 WorkerShutdown shutdown_behavior) { |
| 1481 return new SequencedWorkerPoolTaskRunner(this, shutdown_behavior); | 1488 return new SequencedWorkerPoolTaskRunner(this, shutdown_behavior); |
| 1482 } | 1489 } |
| 1483 | 1490 |
| 1484 bool SequencedWorkerPool::PostWorkerTask( | 1491 bool SequencedWorkerPool::PostWorkerTask( |
| 1485 const tracked_objects::Location& from_here, | 1492 const tracked_objects::Location& from_here, |
| 1486 const Closure& task) { | 1493 OnceClosure task) { |
| 1487 return inner_->PostTask(NULL, SequenceToken(), BLOCK_SHUTDOWN, | 1494 return inner_->PostTask(NULL, SequenceToken(), BLOCK_SHUTDOWN, from_here, |
| 1488 from_here, task, TimeDelta()); | 1495 std::move(task), TimeDelta()); |
| 1489 } | 1496 } |
| 1490 | 1497 |
| 1491 bool SequencedWorkerPool::PostDelayedWorkerTask( | 1498 bool SequencedWorkerPool::PostDelayedWorkerTask( |
| 1492 const tracked_objects::Location& from_here, | 1499 const tracked_objects::Location& from_here, |
| 1493 const Closure& task, | 1500 OnceClosure task, |
| 1494 TimeDelta delay) { | 1501 TimeDelta delay) { |
| 1495 WorkerShutdown shutdown_behavior = | 1502 WorkerShutdown shutdown_behavior = |
| 1496 delay.is_zero() ? BLOCK_SHUTDOWN : SKIP_ON_SHUTDOWN; | 1503 delay.is_zero() ? BLOCK_SHUTDOWN : SKIP_ON_SHUTDOWN; |
| 1497 return inner_->PostTask(NULL, SequenceToken(), shutdown_behavior, | 1504 return inner_->PostTask(NULL, SequenceToken(), shutdown_behavior, from_here, |
| 1498 from_here, task, delay); | 1505 std::move(task), delay); |
| 1499 } | 1506 } |
| 1500 | 1507 |
| 1501 bool SequencedWorkerPool::PostWorkerTaskWithShutdownBehavior( | 1508 bool SequencedWorkerPool::PostWorkerTaskWithShutdownBehavior( |
| 1502 const tracked_objects::Location& from_here, | 1509 const tracked_objects::Location& from_here, |
| 1503 const Closure& task, | 1510 OnceClosure task, |
| 1504 WorkerShutdown shutdown_behavior) { | 1511 WorkerShutdown shutdown_behavior) { |
| 1505 return inner_->PostTask(NULL, SequenceToken(), shutdown_behavior, | 1512 return inner_->PostTask(NULL, SequenceToken(), shutdown_behavior, from_here, |
| 1506 from_here, task, TimeDelta()); | 1513 std::move(task), TimeDelta()); |
| 1507 } | 1514 } |
| 1508 | 1515 |
| 1509 bool SequencedWorkerPool::PostSequencedWorkerTask( | 1516 bool SequencedWorkerPool::PostSequencedWorkerTask( |
| 1510 SequenceToken sequence_token, | 1517 SequenceToken sequence_token, |
| 1511 const tracked_objects::Location& from_here, | 1518 const tracked_objects::Location& from_here, |
| 1512 const Closure& task) { | 1519 OnceClosure task) { |
| 1513 return inner_->PostTask(NULL, sequence_token, BLOCK_SHUTDOWN, | 1520 return inner_->PostTask(NULL, sequence_token, BLOCK_SHUTDOWN, from_here, |
| 1514 from_here, task, TimeDelta()); | 1521 std::move(task), TimeDelta()); |
| 1515 } | 1522 } |
| 1516 | 1523 |
| 1517 bool SequencedWorkerPool::PostDelayedSequencedWorkerTask( | 1524 bool SequencedWorkerPool::PostDelayedSequencedWorkerTask( |
| 1518 SequenceToken sequence_token, | 1525 SequenceToken sequence_token, |
| 1519 const tracked_objects::Location& from_here, | 1526 const tracked_objects::Location& from_here, |
| 1520 const Closure& task, | 1527 OnceClosure task, |
| 1521 TimeDelta delay) { | 1528 TimeDelta delay) { |
| 1522 WorkerShutdown shutdown_behavior = | 1529 WorkerShutdown shutdown_behavior = |
| 1523 delay.is_zero() ? BLOCK_SHUTDOWN : SKIP_ON_SHUTDOWN; | 1530 delay.is_zero() ? BLOCK_SHUTDOWN : SKIP_ON_SHUTDOWN; |
| 1524 return inner_->PostTask(NULL, sequence_token, shutdown_behavior, | 1531 return inner_->PostTask(NULL, sequence_token, shutdown_behavior, from_here, |
| 1525 from_here, task, delay); | 1532 std::move(task), delay); |
| 1526 } | 1533 } |
| 1527 | 1534 |
| 1528 bool SequencedWorkerPool::PostNamedSequencedWorkerTask( | 1535 bool SequencedWorkerPool::PostNamedSequencedWorkerTask( |
| 1529 const std::string& token_name, | 1536 const std::string& token_name, |
| 1530 const tracked_objects::Location& from_here, | 1537 const tracked_objects::Location& from_here, |
| 1531 const Closure& task) { | 1538 OnceClosure task) { |
| 1532 DCHECK(!token_name.empty()); | 1539 DCHECK(!token_name.empty()); |
| 1533 return inner_->PostTask(&token_name, SequenceToken(), BLOCK_SHUTDOWN, | 1540 return inner_->PostTask(&token_name, SequenceToken(), BLOCK_SHUTDOWN, |
| 1534 from_here, task, TimeDelta()); | 1541 from_here, std::move(task), TimeDelta()); |
| 1535 } | 1542 } |
| 1536 | 1543 |
| 1537 bool SequencedWorkerPool::PostSequencedWorkerTaskWithShutdownBehavior( | 1544 bool SequencedWorkerPool::PostSequencedWorkerTaskWithShutdownBehavior( |
| 1538 SequenceToken sequence_token, | 1545 SequenceToken sequence_token, |
| 1539 const tracked_objects::Location& from_here, | 1546 const tracked_objects::Location& from_here, |
| 1540 const Closure& task, | 1547 OnceClosure task, |
| 1541 WorkerShutdown shutdown_behavior) { | 1548 WorkerShutdown shutdown_behavior) { |
| 1542 return inner_->PostTask(NULL, sequence_token, shutdown_behavior, | 1549 return inner_->PostTask(NULL, sequence_token, shutdown_behavior, from_here, |
| 1543 from_here, task, TimeDelta()); | 1550 std::move(task), TimeDelta()); |
| 1544 } | 1551 } |
| 1545 | 1552 |
| 1546 bool SequencedWorkerPool::PostDelayedTask( | 1553 bool SequencedWorkerPool::PostDelayedTask( |
| 1547 const tracked_objects::Location& from_here, | 1554 const tracked_objects::Location& from_here, |
| 1548 const Closure& task, | 1555 OnceClosure task, |
| 1549 TimeDelta delay) { | 1556 TimeDelta delay) { |
| 1550 return PostDelayedWorkerTask(from_here, task, delay); | 1557 return PostDelayedWorkerTask(from_here, std::move(task), delay); |
| 1551 } | 1558 } |
| 1552 | 1559 |
| 1553 bool SequencedWorkerPool::RunsTasksOnCurrentThread() const { | 1560 bool SequencedWorkerPool::RunsTasksOnCurrentThread() const { |
| 1554 return inner_->RunsTasksOnCurrentThread(); | 1561 return inner_->RunsTasksOnCurrentThread(); |
| 1555 } | 1562 } |
| 1556 | 1563 |
| 1557 bool SequencedWorkerPool::IsRunningSequenceOnCurrentThread( | 1564 bool SequencedWorkerPool::IsRunningSequenceOnCurrentThread( |
| 1558 SequenceToken sequence_token) const { | 1565 SequenceToken sequence_token) const { |
| 1559 return inner_->IsRunningSequenceOnCurrentThread(sequence_token); | 1566 return inner_->IsRunningSequenceOnCurrentThread(sequence_token); |
| 1560 } | 1567 } |
| 1561 | 1568 |
| 1562 void SequencedWorkerPool::FlushForTesting() { | 1569 void SequencedWorkerPool::FlushForTesting() { |
| 1563 inner_->CleanupForTesting(); | 1570 inner_->CleanupForTesting(); |
| 1564 } | 1571 } |
| 1565 | 1572 |
| 1566 void SequencedWorkerPool::SignalHasWorkForTesting() { | 1573 void SequencedWorkerPool::SignalHasWorkForTesting() { |
| 1567 inner_->SignalHasWorkForTesting(); | 1574 inner_->SignalHasWorkForTesting(); |
| 1568 } | 1575 } |
| 1569 | 1576 |
| 1570 void SequencedWorkerPool::Shutdown(int max_new_blocking_tasks_after_shutdown) { | 1577 void SequencedWorkerPool::Shutdown(int max_new_blocking_tasks_after_shutdown) { |
| 1571 DCHECK(constructor_task_runner_->BelongsToCurrentThread()); | 1578 DCHECK(constructor_task_runner_->BelongsToCurrentThread()); |
| 1572 inner_->Shutdown(max_new_blocking_tasks_after_shutdown); | 1579 inner_->Shutdown(max_new_blocking_tasks_after_shutdown); |
| 1573 } | 1580 } |
| 1574 | 1581 |
| 1575 bool SequencedWorkerPool::IsShutdownInProgress() { | 1582 bool SequencedWorkerPool::IsShutdownInProgress() { |
| 1576 return inner_->IsShutdownInProgress(); | 1583 return inner_->IsShutdownInProgress(); |
| 1577 } | 1584 } |
| 1578 | 1585 |
| 1579 } // namespace base | 1586 } // namespace base |
| OLD | NEW |