diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-05-24 11:40:17 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-05-24 12:42:11 +0000 |
commit | 5d87695f37678f96492b258bbab36486c59866b4 (patch) | |
tree | be9783bbaf04fb930c4d74ca9c00b5e7954c8bc6 /chromium/base/task/thread_pool/sequence.h | |
parent | 6c11fb357ec39bf087b8b632e2b1e375aef1b38b (diff) |
BASELINE: Update Chromium to 75.0.3770.56
Change-Id: I86d2007fd27a45d5797eee06f4c9369b8b50ac4f
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/base/task/thread_pool/sequence.h')
-rw-r--r-- | chromium/base/task/thread_pool/sequence.h | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/chromium/base/task/thread_pool/sequence.h b/chromium/base/task/thread_pool/sequence.h new file mode 100644 index 00000000000..a4f8495014a --- /dev/null +++ b/chromium/base/task/thread_pool/sequence.h @@ -0,0 +1,128 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_TASK_THREAD_POOL_SEQUENCE_H_ +#define BASE_TASK_THREAD_POOL_SEQUENCE_H_ + +#include <stddef.h> + +#include "base/base_export.h" +#include "base/containers/queue.h" +#include "base/macros.h" +#include "base/optional.h" +#include "base/sequence_token.h" +#include "base/task/task_traits.h" +#include "base/task/thread_pool/scheduler_parallel_task_runner.h" +#include "base/task/thread_pool/sequence_sort_key.h" +#include "base/task/thread_pool/task.h" +#include "base/task/thread_pool/task_source.h" +#include "base/threading/sequence_local_storage_map.h" + +namespace base { +namespace internal { + +// A Sequence holds slots each containing up to a single Task that must be +// executed in posting order. +// +// In comments below, an "empty Sequence" is a Sequence with no slot. +// +// Note: there is a known refcounted-ownership cycle in the Scheduler +// architecture: Sequence -> Task -> TaskRunner -> Sequence -> ... +// This is okay so long as the other owners of Sequence (PriorityQueue and +// SchedulerWorker in alternation and +// SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl::GetWork() +// temporarily) keep running it (and taking Tasks from it as a result). A +// dangling reference cycle would only occur should they release their reference +// to it while it's not empty. In other words, it is only correct for them to +// release it after PopTask() returns false to indicate it was made empty by +// that call (in which case the next PushTask() will return true to indicate to +// the caller that the Sequence should be re-enqueued for execution). +// +// This class is thread-safe. +class BASE_EXPORT Sequence : public TaskSource { + public: + // A Transaction can perform multiple operations atomically on a + // Sequence. While a Transaction is alive, it is guaranteed that nothing + // else will access the Sequence; the Sequence's lock is held for the + // lifetime of the Transaction. + class BASE_EXPORT Transaction : public TaskSource::Transaction { + public: + Transaction(Transaction&& other); + ~Transaction(); + + // Adds |task| in a new slot at the end of the Sequence. Returns true if the + // Sequence needs to be enqueued again. + bool PushTask(Task task); + + Sequence* sequence() const { return static_cast<Sequence*>(task_source()); } + + private: + friend class Sequence; + + explicit Transaction(Sequence* sequence); + + DISALLOW_COPY_AND_ASSIGN(Transaction); + }; + + // |traits| is metadata that applies to all Tasks in the Sequence. + // |task_runner| is a reference to the TaskRunner feeding this TaskSource. + // |task_runner| can be nullptr only for tasks with no TaskRunner, in which + // case |execution_mode| must be kParallel. Otherwise, |execution_mode| is the + // execution mode of |task_runner|. + Sequence(const TaskTraits& traits, + TaskRunner* task_runner, + TaskSourceExecutionMode execution_mode); + + // Begins a Transaction. This method cannot be called on a thread which has an + // active Sequence::Transaction. + Transaction BeginTransaction(); + + ExecutionEnvironment GetExecutionEnvironment() override; + + // Returns a token that uniquely identifies this Sequence. + const SequenceToken& token() const { return token_; } + + SequenceLocalStorageMap* sequence_local_storage() { + return &sequence_local_storage_; + } + + private: + ~Sequence() override; + + // TaskSource: + Optional<Task> TakeTask() override; + bool DidRunTask() override; + SequenceSortKey GetSortKey() const override; + bool IsEmpty() const override; + void Clear() override; + + // Releases reference to TaskRunner. This might cause this object to be + // deleted; therefore, no member access should be made after this method. + void ReleaseTaskRunner(); + + const SequenceToken token_ = SequenceToken::Create(); + + // Queue of tasks to execute. + base::queue<Task> queue_; + + // Holds data stored through the SequenceLocalStorageSlot API. + SequenceLocalStorageMap sequence_local_storage_; + + DISALLOW_COPY_AND_ASSIGN(Sequence); +}; + +struct BASE_EXPORT SequenceAndTransaction { + scoped_refptr<Sequence> sequence; + Sequence::Transaction transaction; + SequenceAndTransaction(scoped_refptr<Sequence> sequence_in, + Sequence::Transaction transaction_in); + SequenceAndTransaction(SequenceAndTransaction&& other); + static SequenceAndTransaction FromSequence(scoped_refptr<Sequence> sequence); + ~SequenceAndTransaction(); +}; + +} // namespace internal +} // namespace base + +#endif // BASE_TASK_THREAD_POOL_SEQUENCE_H_ |