Flutter Engine
The Flutter Engine
event_loop.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
5#include "flutter/shell/platform/glfw/event_loop.h"
6
7#include <atomic>
8#include <utility>
9
10namespace flutter {
11
13 const TaskExpiredCallback& on_task_expired)
14 : main_thread_id_(main_thread_id), on_task_expired_(on_task_expired) {}
15
16EventLoop::~EventLoop() = default;
17
19 return std::this_thread::get_id() == main_thread_id_;
20}
21
22void EventLoop::WaitForEvents(std::chrono::nanoseconds max_wait) {
23 const auto now = TaskTimePoint::clock::now();
24 std::vector<FlutterTask> expired_tasks;
25
26 // Process expired tasks.
27 {
28 std::lock_guard<std::mutex> lock(task_queue_mutex_);
29 while (!task_queue_.empty()) {
30 const auto& top = task_queue_.top();
31 // If this task (and all tasks after this) has not yet expired, there is
32 // nothing more to do. Quit iterating.
33 if (top.fire_time > now) {
34 break;
35 }
36
37 // Make a record of the expired task. Do NOT service the task here
38 // because we are still holding onto the task queue mutex. We don't want
39 // other threads to block on posting tasks onto this thread till we are
40 // done processing expired tasks.
41 expired_tasks.push_back(task_queue_.top().task);
42
43 // Remove the tasks from the delayed tasks queue.
44 task_queue_.pop();
45 }
46 }
47
48 // Fire expired tasks.
49 {
50 // Flushing tasks here without holing onto the task queue mutex.
51 for (const auto& task : expired_tasks) {
52 on_task_expired_(&task);
53 }
54 }
55
56 // Sleep till the next task needs to be processed. If a new task comes
57 // along, the wait will be resolved early because PostTask calls Wake().
58 {
59 TaskTimePoint next_wake;
60 {
61 std::lock_guard<std::mutex> lock(task_queue_mutex_);
62 TaskTimePoint max_wake_timepoint =
64 : now + max_wait;
65 TaskTimePoint next_event_timepoint = task_queue_.empty()
67 : task_queue_.top().fire_time;
68 next_wake = std::min(max_wake_timepoint, next_event_timepoint);
69 }
70 WaitUntil(next_wake);
71 }
72}
73
75 uint64_t flutter_target_time_nanos) {
76 const auto now = TaskTimePoint::clock::now();
77 const int64_t flutter_duration =
78 flutter_target_time_nanos - FlutterEngineGetCurrentTime();
79 return now + std::chrono::nanoseconds(flutter_duration);
80}
81
83 uint64_t flutter_target_time_nanos) {
84 static std::atomic_uint64_t sGlobalTaskOrder(0);
85
86 Task task;
87 task.order = ++sGlobalTaskOrder;
88 task.fire_time = TimePointFromFlutterTime(flutter_target_time_nanos);
89 task.task = flutter_task;
90
91 {
92 std::lock_guard<std::mutex> lock(task_queue_mutex_);
93 task_queue_.push(task);
94
95 // Make sure the queue mutex is unlocked before waking up the loop. In case
96 // the wake causes this thread to be descheduled for the primary thread to
97 // process tasks, the acquisition of the lock on that thread while holding
98 // the lock here momentarily till the end of the scope is a pessimization.
99 }
100 Wake();
101}
102
103} // namespace flutter
void PostTask(FlutterTask flutter_task, uint64_t flutter_target_time_nanos)
Definition: event_loop.cc:82
virtual void Wake()=0
static TaskTimePoint TimePointFromFlutterTime(uint64_t flutter_target_time_nanos)
Definition: event_loop.cc:74
EventLoop(std::thread::id main_thread_id, const TaskExpiredCallback &on_task_expired)
Definition: event_loop.cc:12
std::priority_queue< Task, std::deque< Task >, Task::Comparer > task_queue_
Definition: event_loop.h:83
bool RunsTasksOnCurrentThread() const
Definition: event_loop.cc:18
std::mutex task_queue_mutex_
Definition: event_loop.h:82
virtual ~EventLoop()
virtual void WaitUntil(const TaskTimePoint &time)=0
TaskExpiredCallback on_task_expired_
Definition: event_loop.h:81
std::function< void(const FlutterTask *)> TaskExpiredCallback
Definition: event_loop.h:22
std::thread::id main_thread_id_
Definition: event_loop.h:80
std::chrono::steady_clock::time_point TaskTimePoint
Definition: event_loop.h:50
void WaitForEvents(std::chrono::nanoseconds max_wait=std::chrono::nanoseconds::max())
Definition: event_loop.cc:22
uint64_t FlutterEngineGetCurrentTime()
Get the current time in nanoseconds from the clock used by the flutter engine. This is the system mon...
Definition: embedder.cc:2955
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
TaskTimePoint fire_time
Definition: event_loop.h:68
const uintptr_t id