Flutter Engine
Loading...
Searching...
No Matches
fl_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
5
#include "
flutter/shell/platform/linux/fl_task_runner.h
"
6
#include "
flutter/shell/platform/linux/fl_engine_private.h
"
7
8
static
constexpr
int
kMicrosecondsPerNanosecond
= 1000;
9
static
constexpr
int
kMillisecondsPerMicrosecond
= 1000;
10
11
struct
_FlTaskRunner
{
12
GObject
parent_instance
;
13
14
GWeakRef
engine
;
15
16
GMutex
mutex
;
17
GCond
cond
;
18
19
guint
timeout_source_id
;
20
GList
/*<FlTaskRunnerTask>*/
*
pending_tasks
;
21
};
22
23
typedef
struct
_FlTaskRunnerTask
{
24
// absolute time of task (based on g_get_monotonic_time).
25
gint64
task_time_micros
;
26
27
// flutter task to execute if schedule through
28
// fl_task_runner_post_flutter_task.
29
FlutterTask
task
;
30
}
FlTaskRunnerTask
;
31
32
G_DEFINE_TYPE
(FlTaskRunner, fl_task_runner, G_TYPE_OBJECT)
33
34
// Removes expired tasks from the task queue and executes them.
35
// The execution is performed with mutex unlocked.
36
static
void
fl_task_runner_process_expired_tasks_locked
(FlTaskRunner*
self
) {
37
GList* expired_tasks =
nullptr
;
38
39
gint64 current_time = g_get_monotonic_time();
40
41
GList* l =
self
->pending_tasks;
42
while
(l !=
nullptr
) {
43
FlTaskRunnerTask
* task =
static_cast<
FlTaskRunnerTask
*
>
(l->data);
44
if
(task->
task_time_micros
<= current_time) {
45
GList* link = l;
46
l = l->next;
47
self
->pending_tasks = g_list_remove_link(
self
->pending_tasks, link);
48
expired_tasks = g_list_concat(expired_tasks, link);
49
}
else
{
50
l = l->next;
51
}
52
}
53
54
g_mutex_unlock(&
self
->mutex);
55
56
g_autoptr
(FlEngine)
engine
= FL_ENGINE(g_weak_ref_get(&
self
->engine));
57
if
(
engine
!=
nullptr
) {
58
l = expired_tasks;
59
while
(l !=
nullptr
) {
60
FlTaskRunnerTask
* task =
static_cast<
FlTaskRunnerTask
*
>
(l->data);
61
fl_engine_execute_task
(
engine
, &task->
task
);
62
l = l->next;
63
}
64
}
65
66
g_list_free_full(expired_tasks, g_free);
67
68
g_mutex_lock(&
self
->mutex);
69
}
70
71
static
void
fl_task_runner_tasks_did_change_locked
(FlTaskRunner*
self
);
72
73
// Invoked from a timeout source. Removes and executes expired tasks
74
// and reschedules timeout if needed.
75
static
gboolean
fl_task_runner_on_expired_timeout
(gpointer
data
) {
76
FlTaskRunner*
self
= FL_TASK_RUNNER(
data
);
77
78
g_autoptr
(GMutexLocker) locker = g_mutex_locker_new(&
self
->mutex);
79
(void)locker;
// unused variable
80
81
g_object_ref(
self
);
82
83
self
->timeout_source_id = 0;
84
fl_task_runner_process_expired_tasks_locked
(
self
);
85
86
// reschedule timeout
87
fl_task_runner_tasks_did_change_locked
(
self
);
88
89
g_object_unref(
self
);
90
91
return
FALSE;
92
}
93
94
// Returns the absolute time of next expired task (in microseconds, based on
95
// g_get_monotonic_time). If no task is scheduled returns G_MAXINT64.
96
static
gint64
fl_task_runner_next_task_expiration_time_locked
(
97
FlTaskRunner*
self
) {
98
gint64 min_time = G_MAXINT64;
99
GList* l =
self
->pending_tasks;
100
while
(l !=
nullptr
) {
101
FlTaskRunnerTask
* task =
static_cast<
FlTaskRunnerTask
*
>
(l->data);
102
min_time = MIN(min_time, task->
task_time_micros
);
103
l = l->next;
104
}
105
return
min_time;
106
}
107
108
static
void
fl_task_runner_tasks_did_change_locked
(FlTaskRunner*
self
) {
109
// Reschedule timeout
110
if
(
self
->timeout_source_id != 0) {
111
g_source_remove(
self
->timeout_source_id);
112
self
->timeout_source_id = 0;
113
}
114
gint64 min_time =
fl_task_runner_next_task_expiration_time_locked
(
self
);
115
if
(min_time != G_MAXINT64) {
116
gint64 remaining = MAX(min_time - g_get_monotonic_time(), 0);
117
self
->timeout_source_id =
118
g_timeout_add(remaining /
kMillisecondsPerMicrosecond
+ 1,
119
fl_task_runner_on_expired_timeout
,
self
);
120
}
121
}
122
123
void
fl_task_runner_dispose
(GObject*
object
) {
124
FlTaskRunner*
self
= FL_TASK_RUNNER(
object
);
125
126
g_weak_ref_clear(&
self
->engine);
127
g_mutex_clear(&
self
->mutex);
128
g_cond_clear(&
self
->cond);
129
130
g_list_free_full(
self
->pending_tasks, g_free);
131
if
(
self
->timeout_source_id != 0) {
132
g_source_remove(
self
->timeout_source_id);
133
}
134
135
G_OBJECT_CLASS(fl_task_runner_parent_class)->dispose(
object
);
136
}
137
138
static
void
fl_task_runner_class_init
(FlTaskRunnerClass* klass) {
139
G_OBJECT_CLASS(klass)->dispose =
fl_task_runner_dispose
;
140
}
141
142
static
void
fl_task_runner_init
(FlTaskRunner*
self
) {
143
g_mutex_init(&
self
->mutex);
144
g_cond_init(&
self
->cond);
145
}
146
147
FlTaskRunner*
fl_task_runner_new
(FlEngine*
engine
) {
148
FlTaskRunner*
self
=
149
FL_TASK_RUNNER(g_object_new(fl_task_runner_get_type(),
nullptr
));
150
g_weak_ref_init(&
self
->engine, G_OBJECT(
engine
));
151
return
self
;
152
}
153
154
void
fl_task_runner_post_flutter_task
(FlTaskRunner*
self
,
155
FlutterTask
task,
156
uint64_t target_time_nanos) {
157
g_autoptr
(GMutexLocker) locker = g_mutex_locker_new(&
self
->mutex);
158
(void)locker;
// unused variable
159
160
FlTaskRunnerTask
* runner_task = g_new0(
FlTaskRunnerTask
, 1);
161
runner_task->
task
= task;
162
runner_task->
task_time_micros
=
163
target_time_nanos /
kMicrosecondsPerNanosecond
;
164
165
self
->pending_tasks = g_list_append(
self
->pending_tasks, runner_task);
166
fl_task_runner_tasks_did_change_locked
(
self
);
167
168
// Tasks changed, so wake up anything blocking in fl_task_runner_wait.
169
g_cond_signal(&
self
->cond);
170
}
171
172
void
fl_task_runner_wait
(FlTaskRunner*
self
) {
173
g_autoptr
(GMutexLocker) locker = g_mutex_locker_new(&
self
->mutex);
174
(void)locker;
// unused variable
175
176
g_cond_wait_until(&
self
->cond, &
self
->mutex,
177
fl_task_runner_next_task_expiration_time_locked
(
self
));
178
fl_task_runner_process_expired_tasks_locked
(
self
);
179
fl_task_runner_tasks_did_change_locked
(
self
);
180
}
181
182
void
fl_task_runner_stop_wait
(FlTaskRunner*
self
) {
183
g_cond_signal(&
self
->cond);
184
}
self
return self
Definition
FlutterTextureRegistryRelay.mm:19
engine
FlutterEngine engine
Definition
main.cc:84
G_DEFINE_TYPE
G_DEFINE_TYPE(FlBasicMessageChannelResponseHandle, fl_basic_message_channel_response_handle, G_TYPE_OBJECT) static void fl_basic_message_channel_response_handle_dispose(GObject *object)
Definition
fl_basic_message_channel.cc:37
g_autoptr
g_autoptr(GMutexLocker) locker
fl_engine_execute_task
void fl_engine_execute_task(FlEngine *self, FlutterTask *task)
Definition
fl_engine.cc:1462
fl_engine_private.h
fl_task_runner_wait
void fl_task_runner_wait(FlTaskRunner *self)
Definition
fl_task_runner.cc:172
fl_task_runner_stop_wait
void fl_task_runner_stop_wait(FlTaskRunner *self)
Definition
fl_task_runner.cc:182
fl_task_runner_new
FlTaskRunner * fl_task_runner_new(FlEngine *engine)
Definition
fl_task_runner.cc:147
fl_task_runner_dispose
void fl_task_runner_dispose(GObject *object)
Definition
fl_task_runner.cc:123
fl_task_runner_process_expired_tasks_locked
static void fl_task_runner_process_expired_tasks_locked(FlTaskRunner *self)
Definition
fl_task_runner.cc:36
fl_task_runner_post_flutter_task
void fl_task_runner_post_flutter_task(FlTaskRunner *self, FlutterTask task, uint64_t target_time_nanos)
Definition
fl_task_runner.cc:154
FlTaskRunnerTask
struct _FlTaskRunnerTask FlTaskRunnerTask
fl_task_runner_next_task_expiration_time_locked
static gint64 fl_task_runner_next_task_expiration_time_locked(FlTaskRunner *self)
Definition
fl_task_runner.cc:96
kMillisecondsPerMicrosecond
static constexpr int kMillisecondsPerMicrosecond
Definition
fl_task_runner.cc:9
fl_task_runner_class_init
static void fl_task_runner_class_init(FlTaskRunnerClass *klass)
Definition
fl_task_runner.cc:138
fl_task_runner_tasks_did_change_locked
static void fl_task_runner_tasks_did_change_locked(FlTaskRunner *self)
Definition
fl_task_runner.cc:108
fl_task_runner_on_expired_timeout
static gboolean fl_task_runner_on_expired_timeout(gpointer data)
Definition
fl_task_runner.cc:75
kMicrosecondsPerNanosecond
static constexpr int kMicrosecondsPerNanosecond
Definition
fl_task_runner.cc:8
fl_task_runner_init
static void fl_task_runner_init(FlTaskRunner *self)
Definition
fl_task_runner.cc:142
fl_task_runner.h
_FlTaskRunner
Definition
fl_task_runner.cc:11
_FlTaskRunner::timeout_source_id
guint timeout_source_id
Definition
fl_task_runner.cc:19
_FlTaskRunner::pending_tasks
GList * pending_tasks
Definition
fl_task_runner.cc:20
_FlTaskRunner::engine
GWeakRef engine
Definition
fl_task_runner.cc:14
_FlTaskRunner::mutex
GMutex mutex
Definition
fl_task_runner.cc:16
_FlTaskRunner::parent_instance
GObject parent_instance
Definition
fl_task_runner.cc:12
_FlTaskRunner::cond
GCond cond
Definition
fl_task_runner.cc:17
_FlTaskRunnerTask
Definition
fl_task_runner.cc:23
_FlTaskRunnerTask::task
FlutterTask task
Definition
fl_task_runner.cc:29
_FlTaskRunnerTask::task_time_micros
gint64 task_time_micros
Definition
fl_task_runner.cc:25
FlutterTask
Definition
embedder.h:1848
data
std::shared_ptr< const fml::Mapping > data
Definition
texture_gles.cc:68
shell
platform
linux
fl_task_runner.cc
Generated on Thu Nov 6 2025 16:11:28 for Flutter Engine by
1.9.8