Flutter Engine
The 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 <memory>
10#include <mutex>
11#include <set>
12#include <vector>
13
14#include "flutter/fml/closure.h"
15#include "flutter/fml/delayed_task.h"
16#include "flutter/fml/macros.h"
17#include "flutter/fml/memory/ref_counted.h"
18#include "flutter/fml/synchronization/shared_mutex.h"
19#include "flutter/fml/task_queue_id.h"
20#include "flutter/fml/task_source.h"
21#include "flutter/fml/wakeable.h"
22
23namespace fml {
24
26
27/// A collection of tasks and observers associated with one TaskQueue.
28///
29/// Often a TaskQueue has a one-to-one relationship with a fml::MessageLoop,
30/// this isn't the case when TaskQueues are merged via
31/// \p fml::MessageLoopTaskQueues::Merge.
33 public:
34 using TaskObservers = std::map<intptr_t, fml::closure>;
37 std::unique_ptr<TaskSource> task_source;
38
39 /// Set of the TaskQueueIds which is owned by this TaskQueue. If the set is
40 /// empty, this TaskQueue does not own any other TaskQueues.
41 std::set<TaskQueueId> owner_of;
42
43 /// Identifies the TaskQueue that subsumes this TaskQueue. If it is kUnmerged
44 /// it indicates that this TaskQueue is not owned by any other TaskQueue.
46
48
50
51 private:
52 FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TaskQueueEntry);
53};
54
55enum class FlushType {
56 kSingle,
57 kAll,
58};
59
60/// A singleton container for all tasks and observers associated with all
61/// fml::MessageLoops.
62///
63/// This also wakes up the loop at the required times.
64/// \see fml::MessageLoop
65/// \see fml::Wakeable
67 public:
68 // Lifecycle.
69
71
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
89
90 size_t GetNumPendingTasks(TaskQueueId queue_id) const;
91
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 mutable std::mutex queue_mutex_;
156 std::map<TaskQueueId, std::unique_ptr<TaskQueueEntry>> queue_entries_;
157
158 size_t task_queue_id_counter_ = 0;
159
160 std::atomic_int order_;
161
163};
164
165} // namespace fml
166
167#endif // FLUTTER_FML_MESSAGE_LOOP_TASK_QUEUES_H_
fml::closure GetNextTaskToRun(TaskQueueId queue_id, fml::TimePoint from_time)
bool HasPendingTasks(TaskQueueId queue_id) const
size_t GetNumPendingTasks(TaskQueueId queue_id) const
static TaskSourceGrade GetCurrentTaskSourceGrade()
static MessageLoopTaskQueues * GetInstance()
void ResumeSecondarySource(TaskQueueId queue_id)
void DisposeTasks(TaskQueueId queue_id)
bool Merge(TaskQueueId owner, TaskQueueId subsumed)
bool Unmerge(TaskQueueId owner, TaskQueueId subsumed)
void RegisterTask(TaskQueueId queue_id, const fml::closure &task, fml::TimePoint target_time, fml::TaskSourceGrade task_source_grade=fml::TaskSourceGrade::kUnspecified)
std::vector< fml::closure > GetObserversToNotify(TaskQueueId queue_id) const
void PauseSecondarySource(TaskQueueId queue_id)
bool Owns(TaskQueueId owner, TaskQueueId subsumed) const
Returns true if owner owns the subsumed task queue.
void AddTaskObserver(TaskQueueId queue_id, intptr_t key, const fml::closure &callback)
void RemoveTaskObserver(TaskQueueId queue_id, intptr_t key)
std::set< TaskQueueId > GetSubsumedTaskQueueId(TaskQueueId owner) const
void SetWakeable(TaskQueueId queue_id, fml::Wakeable *wakeable)
void Dispose(TaskQueueId queue_id)
std::set< TaskQueueId > owner_of
std::unique_ptr< TaskSource > task_source
TaskQueueEntry(TaskQueueId created_for)
std::map< intptr_t, fml::closure > TaskObservers
static const size_t kUnmerged
Definition: task_queue_id.h:19
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
#define FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TypeName)
Definition: macros.h:31
Definition: ascii_trie.cc:9
static const TaskQueueId kUnmerged
std::function< void()> closure
Definition: closure.h:14
@ kUnspecified
The absence of a specialized TaskSourceGrade.
static double time(int loops, Benchmark *bench, Target *target)
Definition: nanobench.cpp:394