Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
task_runner.cc
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
6
7#include <atomic>
8#include <utility>
9
10namespace flutter {
11
13 const TaskExpiredCallback& on_task_expired)
14 : get_current_time_(get_current_time),
15 on_task_expired_(std::move(on_task_expired)) {
16 main_thread_id_ = GetCurrentThreadId();
17 task_runner_window_ = TaskRunnerWindow::GetSharedInstance();
18 task_runner_window_->AddDelegate(this);
19}
20
22 task_runner_window_->RemoveDelegate(this);
23}
24
25std::chrono::nanoseconds TaskRunner::ProcessTasks() {
26 const TaskTimePoint now = GetCurrentTimeForTask();
27
28 std::vector<Task> expired_tasks;
29
30 // Process expired tasks.
31 {
32 std::lock_guard<std::mutex> lock(task_queue_mutex_);
33 while (!task_queue_.empty()) {
34 const auto& top = task_queue_.top();
35 // If this task (and all tasks after this) has not yet expired, there is
36 // nothing more to do. Quit iterating.
37 if (top.fire_time > now) {
38 break;
39 }
40
41 // Make a record of the expired task. Do NOT service the task here
42 // because we are still holding onto the task queue mutex. We don't want
43 // other threads to block on posting tasks onto this thread till we are
44 // done processing expired tasks.
45 expired_tasks.push_back(task_queue_.top());
46
47 // Remove the tasks from the delayed tasks queue.
48 task_queue_.pop();
49 }
50 }
51
52 // Fire expired tasks.
53 {
54 // Flushing tasks here without holing onto the task queue mutex.
55 for (const auto& task : expired_tasks) {
56 if (auto flutter_task = std::get_if<FlutterTask>(&task.variant)) {
57 on_task_expired_(flutter_task);
58 } else if (auto closure = std::get_if<TaskClosure>(&task.variant))
59 (*closure)();
60 }
61 }
62
63 // Calculate duration to sleep for on next iteration.
64 {
65 std::lock_guard<std::mutex> lock(task_queue_mutex_);
66 if (task_queue_.empty()) {
67 return std::chrono::nanoseconds::max();
68 } else {
69 return task_queue_.top().fire_time - now;
70 }
71 }
72}
73
74TaskRunner::TaskTimePoint TaskRunner::TimePointFromFlutterTime(
75 uint64_t flutter_target_time_nanos) const {
76 const auto now = GetCurrentTimeForTask();
77 const auto flutter_duration = flutter_target_time_nanos - get_current_time_();
78 return now + std::chrono::nanoseconds(flutter_duration);
79}
80
82 uint64_t flutter_target_time_nanos) {
83 Task task;
84 task.fire_time = TimePointFromFlutterTime(flutter_target_time_nanos);
85 task.variant = flutter_task;
86 EnqueueTask(std::move(task));
87}
88
90 Task task;
91 task.fire_time = GetCurrentTimeForTask();
92 task.variant = std::move(closure);
93 EnqueueTask(std::move(task));
94}
95
96void TaskRunner::PollOnce(std::chrono::milliseconds timeout) {
97 task_runner_window_->PollOnce(timeout);
98}
99
100void TaskRunner::EnqueueTask(Task task) {
101 static std::atomic_uint64_t sGlobalTaskOrder(0);
102
103 task.order = ++sGlobalTaskOrder;
104 {
105 std::lock_guard<std::mutex> lock(task_queue_mutex_);
106 task_queue_.push(task);
107
108 // Make sure the queue mutex is unlocked before waking up the loop. In case
109 // the wake causes this thread to be descheduled for the primary thread to
110 // process tasks, the acquisition of the lock on that thread while holding
111 // the lock here momentarily till the end of the scope is a pessimization.
112 }
113
114 WakeUp();
115}
116
118 return GetCurrentThreadId() == main_thread_id_;
119}
120
121void TaskRunner::WakeUp() {
122 task_runner_window_->WakeUp();
123}
124
125} // namespace flutter
std::chrono::steady_clock::time_point TaskTimePoint
Definition task_runner.h:28
void PostFlutterTask(FlutterTask flutter_task, uint64_t flutter_target_time_nanos)
TaskRunner(CurrentTimeProc get_current_time, const TaskExpiredCallback &on_task_expired)
virtual bool RunsTasksOnCurrentThread() const
std::function< void(const FlutterTask *)> TaskExpiredCallback
Definition task_runner.h:29
void PollOnce(std::chrono::milliseconds timeout)
std::function< void()> TaskClosure
Definition task_runner.h:30
void PostTask(TaskClosure task)
std::chrono::nanoseconds ProcessTasks()
static std::shared_ptr< TaskRunnerWindow > GetSharedInstance()
uint64_t(* CurrentTimeProc)()
Definition task_runner.h:21
Definition ref_ptr.h:261