1*635a8641SAndroid Build Coastguard Worker // Copyright 2016 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_TASK_SCHEDULER_SEQUENCE_H_ 6*635a8641SAndroid Build Coastguard Worker #define BASE_TASK_SCHEDULER_SEQUENCE_H_ 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard Worker #include <stddef.h> 9*635a8641SAndroid Build Coastguard Worker 10*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h" 11*635a8641SAndroid Build Coastguard Worker #include "base/containers/queue.h" 12*635a8641SAndroid Build Coastguard Worker #include "base/macros.h" 13*635a8641SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h" 14*635a8641SAndroid Build Coastguard Worker #include "base/optional.h" 15*635a8641SAndroid Build Coastguard Worker #include "base/sequence_token.h" 16*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/scheduler_lock.h" 17*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/sequence_sort_key.h" 18*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/task.h" 19*635a8641SAndroid Build Coastguard Worker #include "base/threading/sequence_local_storage_map.h" 20*635a8641SAndroid Build Coastguard Worker 21*635a8641SAndroid Build Coastguard Worker namespace base { 22*635a8641SAndroid Build Coastguard Worker namespace internal { 23*635a8641SAndroid Build Coastguard Worker 24*635a8641SAndroid Build Coastguard Worker // A Sequence holds slots each containing up to a single Task that must be 25*635a8641SAndroid Build Coastguard Worker // executed in posting order. 26*635a8641SAndroid Build Coastguard Worker // 27*635a8641SAndroid Build Coastguard Worker // In comments below, an "empty Sequence" is a Sequence with no slot. 28*635a8641SAndroid Build Coastguard Worker // 29*635a8641SAndroid Build Coastguard Worker // Note: there is a known refcounted-ownership cycle in the Scheduler 30*635a8641SAndroid Build Coastguard Worker // architecture: Sequence -> Task -> TaskRunner -> Sequence -> ... 31*635a8641SAndroid Build Coastguard Worker // This is okay so long as the other owners of Sequence (PriorityQueue and 32*635a8641SAndroid Build Coastguard Worker // SchedulerWorker in alternation and 33*635a8641SAndroid Build Coastguard Worker // SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl::GetWork() 34*635a8641SAndroid Build Coastguard Worker // temporarily) keep running it (and taking Tasks from it as a result). A 35*635a8641SAndroid Build Coastguard Worker // dangling reference cycle would only occur should they release their reference 36*635a8641SAndroid Build Coastguard Worker // to it while it's not empty. In other words, it is only correct for them to 37*635a8641SAndroid Build Coastguard Worker // release it after PopTask() returns false to indicate it was made empty by 38*635a8641SAndroid Build Coastguard Worker // that call (in which case the next PushTask() will return true to indicate to 39*635a8641SAndroid Build Coastguard Worker // the caller that the Sequence should be re-enqueued for execution). 40*635a8641SAndroid Build Coastguard Worker // 41*635a8641SAndroid Build Coastguard Worker // This class is thread-safe. 42*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT Sequence : public RefCountedThreadSafe<Sequence> { 43*635a8641SAndroid Build Coastguard Worker public: 44*635a8641SAndroid Build Coastguard Worker Sequence(); 45*635a8641SAndroid Build Coastguard Worker 46*635a8641SAndroid Build Coastguard Worker // Adds |task| in a new slot at the end of the Sequence. Returns true if the 47*635a8641SAndroid Build Coastguard Worker // Sequence was empty before this operation. 48*635a8641SAndroid Build Coastguard Worker bool PushTask(Task task); 49*635a8641SAndroid Build Coastguard Worker 50*635a8641SAndroid Build Coastguard Worker // Transfers ownership of the Task in the front slot of the Sequence to the 51*635a8641SAndroid Build Coastguard Worker // caller. The front slot of the Sequence will be nullptr and remain until 52*635a8641SAndroid Build Coastguard Worker // Pop(). Cannot be called on an empty Sequence or a Sequence whose front slot 53*635a8641SAndroid Build Coastguard Worker // is already nullptr. 54*635a8641SAndroid Build Coastguard Worker // 55*635a8641SAndroid Build Coastguard Worker // Because this method cannot be called on an empty Sequence, the returned 56*635a8641SAndroid Build Coastguard Worker // Optional<Task> is never nullptr. An Optional is used in preparation for the 57*635a8641SAndroid Build Coastguard Worker // merge between TaskScheduler and TaskQueueManager (in Blink). 58*635a8641SAndroid Build Coastguard Worker // https://crbug.com/783309 59*635a8641SAndroid Build Coastguard Worker Optional<Task> TakeTask(); 60*635a8641SAndroid Build Coastguard Worker 61*635a8641SAndroid Build Coastguard Worker // Removes the front slot of the Sequence. The front slot must have been 62*635a8641SAndroid Build Coastguard Worker // emptied by TakeTask() before this is called. Cannot be called on an empty 63*635a8641SAndroid Build Coastguard Worker // Sequence. Returns true if the Sequence is empty after this operation. 64*635a8641SAndroid Build Coastguard Worker bool Pop(); 65*635a8641SAndroid Build Coastguard Worker 66*635a8641SAndroid Build Coastguard Worker // Returns a SequenceSortKey representing the priority of the Sequence. Cannot 67*635a8641SAndroid Build Coastguard Worker // be called on an empty Sequence. 68*635a8641SAndroid Build Coastguard Worker SequenceSortKey GetSortKey() const; 69*635a8641SAndroid Build Coastguard Worker 70*635a8641SAndroid Build Coastguard Worker // Returns a token that uniquely identifies this Sequence. token()71*635a8641SAndroid Build Coastguard Worker const SequenceToken& token() const { return token_; } 72*635a8641SAndroid Build Coastguard Worker sequence_local_storage()73*635a8641SAndroid Build Coastguard Worker SequenceLocalStorageMap* sequence_local_storage() { 74*635a8641SAndroid Build Coastguard Worker return &sequence_local_storage_; 75*635a8641SAndroid Build Coastguard Worker } 76*635a8641SAndroid Build Coastguard Worker 77*635a8641SAndroid Build Coastguard Worker private: 78*635a8641SAndroid Build Coastguard Worker friend class RefCountedThreadSafe<Sequence>; 79*635a8641SAndroid Build Coastguard Worker ~Sequence(); 80*635a8641SAndroid Build Coastguard Worker 81*635a8641SAndroid Build Coastguard Worker const SequenceToken token_ = SequenceToken::Create(); 82*635a8641SAndroid Build Coastguard Worker 83*635a8641SAndroid Build Coastguard Worker // Synchronizes access to all members. 84*635a8641SAndroid Build Coastguard Worker mutable SchedulerLock lock_; 85*635a8641SAndroid Build Coastguard Worker 86*635a8641SAndroid Build Coastguard Worker // Queue of tasks to execute. 87*635a8641SAndroid Build Coastguard Worker base::queue<Task> queue_; 88*635a8641SAndroid Build Coastguard Worker 89*635a8641SAndroid Build Coastguard Worker // Number of tasks contained in the Sequence for each priority. 90*635a8641SAndroid Build Coastguard Worker size_t num_tasks_per_priority_[static_cast<int>(TaskPriority::HIGHEST) + 1] = 91*635a8641SAndroid Build Coastguard Worker {}; 92*635a8641SAndroid Build Coastguard Worker 93*635a8641SAndroid Build Coastguard Worker // Holds data stored through the SequenceLocalStorageSlot API. 94*635a8641SAndroid Build Coastguard Worker SequenceLocalStorageMap sequence_local_storage_; 95*635a8641SAndroid Build Coastguard Worker 96*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(Sequence); 97*635a8641SAndroid Build Coastguard Worker }; 98*635a8641SAndroid Build Coastguard Worker 99*635a8641SAndroid Build Coastguard Worker } // namespace internal 100*635a8641SAndroid Build Coastguard Worker } // namespace base 101*635a8641SAndroid Build Coastguard Worker 102*635a8641SAndroid Build Coastguard Worker #endif // BASE_TASK_SCHEDULER_SEQUENCE_H_ 103