1 // 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 10 #include <memory> 11 #include <queue> 12 13 #include "base/base_export.h" 14 #include "base/macros.h" 15 #include "base/memory/ref_counted.h" 16 #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" 20 21 namespace base { 22 namespace internal { 23 24 // A sequence holds tasks that must be executed in posting order. 25 // 26 // Note: there is a known refcounted-ownership cycle in the Scheduler 27 // architecture: Sequence -> Task -> TaskRunner -> Sequence -> ... 28 // This is okay so long as the other owners of Sequence (PriorityQueue and 29 // SchedulerWorker in alternation and 30 // SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl::GetWork() 31 // temporarily) keep running it (and taking Tasks from it as a result). A 32 // dangling reference cycle would only occur should they release their reference 33 // to it while it's not empty. In other words, it is only correct for them to 34 // release it after PopTask() returns false to indicate it was made empty by 35 // that call (in which case the next PushTask() will return true to indicate to 36 // the caller that the Sequence should be re-enqueued for execution). 37 // 38 // This class is thread-safe. 39 class BASE_EXPORT Sequence : public RefCountedThreadSafe<Sequence> { 40 public: 41 Sequence(); 42 43 // Adds |task| at the end of the sequence's queue. Returns true if the 44 // sequence was empty before this operation. 45 bool PushTask(std::unique_ptr<Task> task); 46 47 // Returns the task in front of the sequence's queue, if any. 48 const Task* PeekTask() const; 49 50 // Removes the task in front of the sequence's queue. Returns true if the 51 // sequence is empty after this operation. Cannot be called on an empty 52 // sequence. 53 bool PopTask(); 54 55 // Returns a SequenceSortKey representing the priority of the sequence. Cannot 56 // be called on an empty sequence. 57 SequenceSortKey GetSortKey() const; 58 59 private: 60 friend class RefCountedThreadSafe<Sequence>; 61 ~Sequence(); 62 63 // Synchronizes access to all members. 64 mutable SchedulerLock lock_; 65 66 // Queue of tasks to execute. 67 std::queue<std::unique_ptr<Task>> queue_; 68 69 // Number of tasks contained in the sequence for each priority. 70 size_t num_tasks_per_priority_[static_cast<int>(TaskPriority::HIGHEST) + 1] = 71 {}; 72 73 DISALLOW_COPY_AND_ASSIGN(Sequence); 74 }; 75 76 } // namespace internal 77 } // namespace base 78 79 #endif // BASE_TASK_SCHEDULER_SEQUENCE_H_ 80