Flutter Engine
message_loop_task_queues.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter 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 FLUTTER_FML_MESSAGE_LOOP_TASK_QUEUES_H_
6 #define FLUTTER_FML_MESSAGE_LOOP_TASK_QUEUES_H_
7 
8 #include <map>
9 #include <mutex>
10 #include <set>
11 #include <vector>
12 
13 #include "flutter/fml/closure.h"
14 #include "flutter/fml/delayed_task.h"
15 #include "flutter/fml/macros.h"
16 #include "flutter/fml/memory/ref_counted.h"
17 #include "flutter/fml/synchronization/shared_mutex.h"
18 #include "flutter/fml/task_queue_id.h"
19 #include "flutter/fml/task_source.h"
20 #include "flutter/fml/wakeable.h"
21 
22 namespace fml {
23 
25 
26 /// A collection of tasks and observers associated with one TaskQueue.
27 ///
28 /// Often a TaskQueue has a one-to-one relationship with a fml::MessageLoop,
29 /// this isn't the case when TaskQueues are merged via
30 /// \p fml::MessageLoopTaskQueues::Merge.
32  public:
33  using TaskObservers = std::map<intptr_t, fml::closure>;
36  std::unique_ptr<TaskSource> task_source;
37 
38  /// Set of the TaskQueueIds which is owned by this TaskQueue. If the set is
39  /// empty, this TaskQueue does not own any other TaskQueues.
40  std::set<TaskQueueId> owner_of;
41 
42  /// Identifies the TaskQueue that subsumes this TaskQueue. If it is _kUnmerged
43  /// it indicates that this TaskQueue is not owned by any other TaskQueue.
45 
47 
48  explicit TaskQueueEntry(TaskQueueId created_for);
49 
50  private:
51  FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TaskQueueEntry);
52 };
53 
54 enum class FlushType {
55  kSingle,
56  kAll,
57 };
58 
59 /// A singleton container for all tasks and observers associated with all
60 /// fml::MessageLoops.
61 ///
62 /// This also wakes up the loop at the required times.
63 /// \see fml::MessageLoop
64 /// \see fml::Wakeable
66  : public fml::RefCountedThreadSafe<MessageLoopTaskQueues> {
67  public:
68  // Lifecycle.
69 
70  static fml::RefPtr<MessageLoopTaskQueues> GetInstance();
71 
72  TaskQueueId CreateTaskQueue();
73 
74  void Dispose(TaskQueueId queue_id);
75 
76  void DisposeTasks(TaskQueueId queue_id);
77 
78  // Tasks methods.
79 
80  void RegisterTask(TaskQueueId queue_id,
81  const fml::closure& task,
82  fml::TimePoint target_time,
83  fml::TaskSourceGrade task_source_grade =
85 
86  bool HasPendingTasks(TaskQueueId queue_id) const;
87 
88  fml::closure GetNextTaskToRun(TaskQueueId queue_id, fml::TimePoint from_time);
89 
90  size_t GetNumPendingTasks(TaskQueueId queue_id) const;
91 
92  static TaskSourceGrade GetCurrentTaskSourceGrade();
93 
94  // Observers methods.
95 
96  void AddTaskObserver(TaskQueueId queue_id,
97  intptr_t key,
98  const fml::closure& callback);
99 
100  void RemoveTaskObserver(TaskQueueId queue_id, intptr_t key);
101 
102  std::vector<fml::closure> GetObserversToNotify(TaskQueueId queue_id) const;
103 
104  // Misc.
105 
106  void SetWakeable(TaskQueueId queue_id, fml::Wakeable* wakeable);
107 
108  // Invariants for merge and un-merge
109  // 1. RegisterTask will always submit to the queue_id that is passed
110  // to it. It is not aware of whether a queue is merged or not. Same with
111  // task observers.
112  // 2. When we get the tasks to run now, we look at both the queue_ids
113  // for the owner and the subsumed task queues.
114  // 3. One TaskQueue can subsume multiple other TaskQueues. A TaskQueue can be
115  // in exactly one of the following three states:
116  // a. Be an owner of multiple other TaskQueues.
117  // b. Be subsumed by a TaskQueue (an owner can never be subsumed).
118  // c. Be independent, i.e, neither owner nor be subsumed.
119  //
120  // Methods currently aware of the merged state of the queues:
121  // HasPendingTasks, GetNextTaskToRun, GetNumPendingTasks
122  bool Merge(TaskQueueId owner, TaskQueueId subsumed);
123 
124  // Will return false if the owner has not been merged before, or owner was
125  // subsumed by others, or subsumed wasn't subsumed by others, or owner
126  // didn't own the given subsumed queue id.
127  bool Unmerge(TaskQueueId owner, TaskQueueId subsumed);
128 
129  /// Returns \p true if \p owner owns the \p subsumed task queue.
130  bool Owns(TaskQueueId owner, TaskQueueId subsumed) const;
131 
132  // Returns the subsumed task queue if any or |TaskQueueId::kUnmerged|
133  // otherwise.
134  std::set<TaskQueueId> GetSubsumedTaskQueueId(TaskQueueId owner) const;
135 
136  void PauseSecondarySource(TaskQueueId queue_id);
137 
138  void ResumeSecondarySource(TaskQueueId queue_id);
139 
140  private:
141  class MergedQueuesRunner;
142 
144 
146 
147  void WakeUpUnlocked(TaskQueueId queue_id, fml::TimePoint time) const;
148 
149  bool HasPendingTasksUnlocked(TaskQueueId queue_id) const;
150 
151  TaskSource::TopTask PeekNextTaskUnlocked(TaskQueueId owner) const;
152 
153  fml::TimePoint GetNextWakeTimeUnlocked(TaskQueueId queue_id) const;
154 
155  static std::mutex creation_mutex_;
156  static fml::RefPtr<MessageLoopTaskQueues> instance_;
157 
158  mutable std::mutex queue_mutex_;
159  std::map<TaskQueueId, std::unique_ptr<TaskQueueEntry>> queue_entries_;
160 
161  size_t task_queue_id_counter_;
162 
163  std::atomic_int order_;
164 
168 };
169 
170 } // namespace fml
171 
172 #endif // FLUTTER_FML_MESSAGE_LOOP_TASK_QUEUES_H_
std::set< TaskQueueId > owner_of
#define FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TypeName)
Definition: macros.h:31
std::map< intptr_t, fml::closure > TaskObservers
#define FML_FRIEND_REF_COUNTED_THREAD_SAFE(T)
Definition: ref_counted.h:125
TaskQueueEntry(TaskQueueId created_for)
FlKeyEvent FlKeyResponderAsyncCallback callback
Definition: ascii_trie.cc:9
std::function< void()> closure
Definition: closure.h:14
#define FML_FRIEND_MAKE_REF_COUNTED(T)
Definition: ref_counted.h:131
TaskQueueId created_for
TaskObservers task_observers
std::unique_ptr< TaskSource > task_source
static const TaskQueueId _kUnmerged
Wakeable * wakeable
static const size_t kUnmerged
Definition: task_queue_id.h:19
TaskQueueId subsumed_by
The absence of a specialized TaskSourceGrade.