blob: ec5e8c15092fda46674452c99f8cfcd160f07c7c [file] [log] [blame]
fdorayc48d5f092016-03-17 01:57:421// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_TASK_SCHEDULER_SEQUENCE_H_
6#define BASE_TASK_SCHEDULER_SEQUENCE_H_
7
8#include <stddef.h>
9
fdorayc48d5f092016-03-17 01:57:4210#include "base/base_export.h"
Brett Wilson3d88e7762017-08-14 19:54:3811#include "base/containers/queue.h"
fdorayc48d5f092016-03-17 01:57:4212#include "base/macros.h"
13#include "base/memory/ref_counted.h"
Robert Liaod07daf92017-12-18 01:38:0714#include "base/optional.h"
fdoray4bf182a2016-07-26 23:48:0615#include "base/sequence_token.h"
fdorayc48d5f092016-03-17 01:57:4216#include "base/task_scheduler/scheduler_lock.h"
17#include "base/task_scheduler/sequence_sort_key.h"
18#include "base/task_scheduler/task.h"
19#include "base/task_scheduler/task_traits.h"
Jeffrey Hec42cc0082017-06-13 14:39:1620#include "base/threading/sequence_local_storage_map.h"
fdorayc48d5f092016-03-17 01:57:4221
22namespace base {
23namespace internal {
24
fdoray0c97aa32016-10-12 12:21:2725// A Sequence holds slots each containing up to a single Task that must be
26// executed in posting order.
27//
28// In comments below, an "empty Sequence" is a Sequence with no slot.
gaba8e9e2c2016-05-02 21:17:4729//
30// Note: there is a known refcounted-ownership cycle in the Scheduler
31// architecture: Sequence -> Task -> TaskRunner -> Sequence -> ...
32// This is okay so long as the other owners of Sequence (PriorityQueue and
robliao7a584392016-06-22 18:36:4133// SchedulerWorker in alternation and
34// SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl::GetWork()
gaba8e9e2c2016-05-02 21:17:4735// temporarily) keep running it (and taking Tasks from it as a result). A
36// dangling reference cycle would only occur should they release their reference
37// to it while it's not empty. In other words, it is only correct for them to
38// release it after PopTask() returns false to indicate it was made empty by
39// that call (in which case the next PushTask() will return true to indicate to
40// the caller that the Sequence should be re-enqueued for execution).
41//
fdorayc48d5f092016-03-17 01:57:4242// This class is thread-safe.
43class BASE_EXPORT Sequence : public RefCountedThreadSafe<Sequence> {
44 public:
45 Sequence();
46
fdoray0c97aa32016-10-12 12:21:2747 // Adds |task| in a new slot at the end of the Sequence. Returns true if the
48 // Sequence was empty before this operation.
Robert Liaod07daf92017-12-18 01:38:0749 bool PushTask(Task task);
fdorayc48d5f092016-03-17 01:57:4250
fdoray0c97aa32016-10-12 12:21:2751 // Transfers ownership of the Task in the front slot of the Sequence to the
52 // caller. The front slot of the Sequence will be nullptr and remain until
53 // Pop(). Cannot be called on an empty Sequence or a Sequence whose front slot
54 // is already nullptr.
Robert Liaod07daf92017-12-18 01:38:0755 //
56 // Because this method cannot be called on an empty Sequence, the returned
57 // Optional<Task> is never nullptr. An Optional is used in preparation for the
58 // merge between TaskScheduler and TaskQueueManager (in Blink).
59 // https://crbug.com/783309
60 Optional<Task> TakeTask();
fdorayc48d5f092016-03-17 01:57:4261
fdoray0c97aa32016-10-12 12:21:2762 // Returns the TaskTraits of the Task in front of the Sequence. Cannot be
63 // called on an empty Sequence or on a Sequence whose front slot is empty.
64 TaskTraits PeekTaskTraits() const;
fdorayc48d5f092016-03-17 01:57:4265
fdoray0c97aa32016-10-12 12:21:2766 // Removes the front slot of the Sequence. The front slot must have been
67 // emptied by TakeTask() before this is called. Cannot be called on an empty
68 // Sequence. Returns true if the Sequence is empty after this operation.
69 bool Pop();
70
71 // Returns a SequenceSortKey representing the priority of the Sequence. Cannot
72 // be called on an empty Sequence.
fdorayc48d5f092016-03-17 01:57:4273 SequenceSortKey GetSortKey() const;
74
fdoray4bf182a2016-07-26 23:48:0675 // Returns a token that uniquely identifies this Sequence.
76 const SequenceToken& token() const { return token_; }
77
Jeffrey Hec42cc0082017-06-13 14:39:1678 SequenceLocalStorageMap* sequence_local_storage() {
79 return &sequence_local_storage_;
80 }
81
fdorayc48d5f092016-03-17 01:57:4282 private:
83 friend class RefCountedThreadSafe<Sequence>;
84 ~Sequence();
85
fdoray4bf182a2016-07-26 23:48:0686 const SequenceToken token_ = SequenceToken::Create();
87
fdorayc48d5f092016-03-17 01:57:4288 // Synchronizes access to all members.
89 mutable SchedulerLock lock_;
90
91 // Queue of tasks to execute.
Robert Liaod07daf92017-12-18 01:38:0792 base::queue<Task> queue_;
fdorayc48d5f092016-03-17 01:57:4293
fdoray0c97aa32016-10-12 12:21:2794 // Number of tasks contained in the Sequence for each priority.
fdorayc48d5f092016-03-17 01:57:4295 size_t num_tasks_per_priority_[static_cast<int>(TaskPriority::HIGHEST) + 1] =
96 {};
97
Jeffrey Hec42cc0082017-06-13 14:39:1698 // Holds data stored through the SequenceLocalStorageSlot API.
99 SequenceLocalStorageMap sequence_local_storage_;
100
fdorayc48d5f092016-03-17 01:57:42101 DISALLOW_COPY_AND_ASSIGN(Sequence);
102};
103
104} // namespace internal
105} // namespace base
106
107#endif // BASE_TASK_SCHEDULER_SEQUENCE_H_