Chromium Code Reviews| Index: base/threading/sequenced_worker_pool.cc |
| diff --git a/base/threading/sequenced_worker_pool.cc b/base/threading/sequenced_worker_pool.cc |
| index ed79897fd450f5e796bc9db5e79ffeeb59eed2ab..117e6dac9421ea8ed5570bbbe97cede21b7fb782 100644 |
| --- a/base/threading/sequenced_worker_pool.cc |
| +++ b/base/threading/sequenced_worker_pool.cc |
| @@ -296,7 +296,7 @@ class SequencedWorkerPool::Inner { |
| ~Inner(); |
| - SequenceToken GetSequenceToken(); |
| + static SequenceToken GetSequenceToken(); |
| SequenceToken GetNamedSequenceToken(const std::string& name); |
| @@ -314,6 +314,9 @@ class SequencedWorkerPool::Inner { |
| bool IsRunningSequenceOnCurrentThread(SequenceToken sequence_token) const; |
| + void SetRunningTaskInfoForCurrentThread(SequenceToken sequence_token, |
| + WorkerShutdown shutdown_behavior); |
| + |
| void CleanupForTesting(); |
| void SignalHasWorkForTesting(); |
| @@ -583,6 +586,7 @@ SequencedWorkerPool::Inner::~Inner() { |
| testing_observer_->OnDestruct(); |
| } |
| +// static |
| SequencedWorkerPool::SequenceToken |
| SequencedWorkerPool::Inner::GetSequenceToken() { |
| // Need to add one because StaticAtomicSequenceNumber starts at zero, which |
| @@ -683,6 +687,21 @@ bool SequencedWorkerPool::Inner::IsRunningSequenceOnCurrentThread( |
| sequence_token.Equals(found->second->task_sequence_token()); |
| } |
| +void SequencedWorkerPool::Inner::SetRunningTaskInfoForCurrentThread( |
| + SequenceToken sequence_token, |
| + WorkerShutdown shutdown_behavior) { |
| + AutoLock lock(lock_); |
| + ThreadMap::const_iterator found = threads_.find(PlatformThread::CurrentId()); |
| + DCHECK(found != threads_.end()); |
| + DCHECK(found->second->is_processing_task()); |
| + DCHECK(!found->second->task_sequence_token().IsValid()); |
| + found->second->set_running_task_info(sequence_token, shutdown_behavior); |
| + |
| + // Mark the sequence token as in use. |
| + bool success = current_sequences_.insert(sequence_token.id_).second; |
| + DCHECK(success); |
| +} |
| + |
| // See https://code.google.com/p/chromium/issues/detail?id=168415 |
| void SequencedWorkerPool::Inner::CleanupForTesting() { |
| DCHECK(!RunsTasksOnCurrentThread()); |
| @@ -807,6 +826,11 @@ void SequencedWorkerPool::Inner::ThreadLoop(Worker* this_worker) { |
| tracked_objects::ThreadData::TallyRunOnNamedThreadIfTracking( |
| task, stopwatch); |
| + // Update the sequence token in case it has been set from within the |
| + // task, so it can be removed from the set of currently running |
| + // sequences in DidRunWorkerTask() below. |
| + task.sequence_token_id = this_worker->task_sequence_token().id_; |
|
danakj
2015/11/20 19:18:43
Is this line captured in any unit tests?
Bernhard Bauer
2015/12/10 16:09:58
Yes, SequencedWorkerPoolTest.GetSequencedTaskRunne
|
| + |
| // Make sure our task is erased outside the lock for the |
| // same reason we do this with delete_these_oustide_lock. |
| // Also, do it before calling reset_running_task_info() so |
| @@ -1181,13 +1205,24 @@ SequencedWorkerPool::GetSequenceTokenForCurrentThread() { |
| } |
| // static |
| -scoped_refptr<SequencedWorkerPool> |
| -SequencedWorkerPool::GetWorkerPoolForCurrentThread() { |
| +scoped_refptr<SequencedTaskRunner> |
| +SequencedWorkerPool::GetSequencedTaskRunnerForCurrentThread() { |
| Worker* worker = Worker::GetForCurrentThread(); |
| if (!worker) |
| return nullptr; |
| - return worker->worker_pool(); |
| + scoped_refptr<SequencedWorkerPool> pool = worker->worker_pool(); |
| + SequenceToken sequence_token = worker->task_sequence_token(); |
| + WorkerShutdown shutdown_behavior = worker->task_shutdown_behavior(); |
| + if (!sequence_token.IsValid()) { |
| + sequence_token = Inner::GetSequenceToken(); |
| + pool->inner_->SetRunningTaskInfoForCurrentThread(sequence_token, |
| + shutdown_behavior); |
| + } |
| + |
| + DCHECK(pool->IsRunningSequenceOnCurrentThread(sequence_token)); |
| + return new SequencedWorkerPoolSequencedTaskRunner( |
| + std::move(pool), sequence_token, shutdown_behavior); |
| } |
| SequencedWorkerPool::SequencedWorkerPool(size_t max_threads, |
| @@ -1206,8 +1241,7 @@ SequencedWorkerPool::SequencedWorkerPool(size_t max_threads, |
| SequencedWorkerPool::~SequencedWorkerPool() {} |
| void SequencedWorkerPool::OnDestruct() const { |
| - // Avoid deleting ourselves on a worker thread (which would |
| - // deadlock). |
| + // Avoid deleting ourselves on a worker thread (which would deadlock). |
| if (RunsTasksOnCurrentThread()) { |
| constructor_task_runner_->DeleteSoon(FROM_HERE, this); |
| } else { |
| @@ -1215,8 +1249,9 @@ void SequencedWorkerPool::OnDestruct() const { |
| } |
| } |
| +// static |
| SequencedWorkerPool::SequenceToken SequencedWorkerPool::GetSequenceToken() { |
| - return inner_->GetSequenceToken(); |
| + return Inner::GetSequenceToken(); |
| } |
| SequencedWorkerPool::SequenceToken SequencedWorkerPool::GetNamedSequenceToken( |