| Flutter Linux Embedder |

Classes | Typedefs | Functions | Variables
fl_task_runner.cc File Reference
`#include "flutter/shell/platform/linux/fl_task_runner.h"`
`#include "flutter/shell/platform/linux/fl_engine_private.h"`

Go to the source code of this file.

## Classes
struct | _FlTaskRunner
struct | _FlTaskRunnerTask

## Typedefs
typedef struct _FlTaskRunnerTask | FlTaskRunnerTask

## Functions
static void | fl_task_runner_process_expired_tasks_locked (FlTaskRunner *self)
static void | fl_task_runner_tasks_did_change_locked (FlTaskRunner *self)
static gboolean | fl_task_runner_on_expired_timeout (gpointer data)
static gint64 | fl_task_runner_next_task_expiration_time_locked (FlTaskRunner *self)
void | fl_task_runner_dispose (GObject *object)
static void | fl_task_runner_class_init (FlTaskRunnerClass *klass)
static void | fl_task_runner_init (FlTaskRunner *self)
FlTaskRunner * | fl_task_runner_new (FlEngine *engine)
void | fl_task_runner_post_flutter_task (FlTaskRunner *self, FlutterTask task, uint64_t target_time_nanos)
void | fl_task_runner_post_callback (FlTaskRunner *self, void(*callback)(gpointer data), gpointer data)
void | fl_task_runner_block_main_thread (FlTaskRunner *self)
void | fl_task_runner_release_main_thread (FlTaskRunner *self)

## Variables
static constexpr int | kMicrosecondsPerNanosecond = 1000
static constexpr int | kMillisecondsPerMicrosecond = 1000

## Typedef Documentation

## ◆ FlTaskRunnerTask

typedef struct _FlTaskRunnerTask FlTaskRunnerTask

## Function Documentation

## ◆ fl_task_runner_block_main_thread()

void fl_task_runner_block_main_thread | ( | FlTaskRunner * | task_runner | ) |

fl_task_runner_block_main_thread: @task_runner: an #FlTaskRunner.

Blocks main thread until fl_task_runner_release_main_thread is called. While main thread is blocked tasks posted to #FlTaskRunner are executed as usual. Must be invoked on main thread.

Definition at line 203 of file fl_task_runner.cc.

203 {
204 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
205 (void)locker; // unused variable
206
207 g_return_if_fail(self->blocking_main_thread == FALSE);
208
209 g_object_ref(self);
210
211 self->blocking_main_thread = true;
212 while (self->blocking_main_thread) {
213 g_cond_wait_until(&self->cond, &self->mutex,
214 fl_task_runner_next_task_expiration_time_locked(self));
215 fl_task_runner_process_expired_tasks_locked(self);
216 }
217
218 // Tasks might have changed in the meanwhile, reschedule timeout
219 fl_task_runner_tasks_did_change_locked(self);
220
221 g_object_unref(self);
222 }
fl_task_runner_process_expired_tasks_locked
static void fl_task_runner_process_expired_tasks_locked(FlTaskRunner *self)
Definition: fl_task_runner.cc:43
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:107
fl_task_runner_tasks_did_change_locked
static void fl_task_runner_tasks_did_change_locked(FlTaskRunner *self)
Definition: fl_task_runner.cc:119

References fl_task_runner_next_task_expiration_time_locked(), fl_task_runner_process_expired_tasks_locked(), and fl_task_runner_tasks_did_change_locked().

Referenced by fl_compositor_opengl_wait_for_frame().

## ◆ fl_task_runner_class_init()

static void fl_task_runner_class_init | ( | FlTaskRunnerClass * | klass | ) |
| static

Definition at line 158 of file fl_task_runner.cc.

158 {
159 G_OBJECT_CLASS(klass)->dispose = fl_task_runner_dispose;
160 }
fl_task_runner_dispose
void fl_task_runner_dispose(GObject *object)
Definition: fl_task_runner.cc:139

References fl_task_runner_dispose().

## ◆ fl_task_runner_dispose()

void fl_task_runner_dispose | ( | GObject * | object | ) |

Definition at line 139 of file fl_task_runner.cc.

139 {
140 FlTaskRunner* self = FL_TASK_RUNNER(object);
141
142 // this should never happen because the task runner is retained while blocking
143 // main thread
144 g_assert(!self->blocking_main_thread);
145
146 g_weak_ref_clear(&self->engine);
147 g_mutex_clear(&self->mutex);
148 g_cond_clear(&self->cond);
149
150 g_list_free_full(self->pending_tasks, g_free);
151 if (self->timeout_source_id != 0) {
152 g_source_remove(self->timeout_source_id);
153 }
154
155 G_OBJECT_CLASS(fl_task_runner_parent_class)->dispose(object);
156 }

Referenced by fl_task_runner_class_init().

## ◆ fl_task_runner_init()

static void fl_task_runner_init | ( | FlTaskRunner * | self | ) |
| static

Definition at line 162 of file fl_task_runner.cc.

162 {
163 g_mutex_init(&self->mutex);
164 g_cond_init(&self->cond);
165 }

## ◆ fl_task_runner_new()

FlTaskRunner* fl_task_runner_new | ( | FlEngine * | engine | ) |

fl_task_runner_new: @engine: the #FlEngine owning the task runner.

Creates new task runner instance.

Returns: an #FlTaskRunner.

Definition at line 167 of file fl_task_runner.cc.

167 {
168 FlTaskRunner* self =
169 FL_TASK_RUNNER(g_object_new(fl_task_runner_get_type(), nullptr));
170 g_weak_ref_init(&self->engine, G_OBJECT(engine));
171 return self;
172 }

Referenced by fl_engine_init().

## ◆ fl_task_runner_next_task_expiration_time_locked()

static gint64 fl_task_runner_next_task_expiration_time_locked | ( | FlTaskRunner * | self | ) |
| static

Definition at line 107 of file fl_task_runner.cc.

108 {
109 gint64 min_time = G_MAXINT64;
110 GList* l = self->pending_tasks;
111 while (l != nullptr) {
112 FlTaskRunnerTask* task = static_cast<FlTaskRunnerTask*>(l->data);
113 min_time = MIN(min_time, task->task_time_micros);
114 l = l->next;
115 }
116 return min_time;
117 }
_FlTaskRunnerTask
Definition: fl_task_runner.cc:24
_FlTaskRunnerTask::task_time_micros
gint64 task_time_micros
Definition: fl_task_runner.cc:26

References _FlTaskRunnerTask::task_time_micros.

Referenced by fl_task_runner_block_main_thread(), and fl_task_runner_tasks_did_change_locked().

## ◆ fl_task_runner_on_expired_timeout()

static gboolean fl_task_runner_on_expired_timeout | ( | gpointer | data | ) |
| static

Definition at line 86 of file fl_task_runner.cc.

86 {
87 FlTaskRunner* self = FL_TASK_RUNNER(data);
88
89 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
90 (void)locker; // unused variable
91
92 g_object_ref(self);
93
94 self->timeout_source_id = 0;
95 fl_task_runner_process_expired_tasks_locked(self);
96
97 // reschedule timeout
98 fl_task_runner_tasks_did_change_locked(self);
99
100 g_object_unref(self);
101
102 return FALSE;
103 }

References fl_task_runner_process_expired_tasks_locked(), and fl_task_runner_tasks_did_change_locked().

Referenced by fl_task_runner_tasks_did_change_locked().

## ◆ fl_task_runner_post_callback()

void fl_task_runner_post_callback | ( | FlTaskRunner * | task_runner,
|  | void(*)(gpointer data) | callback,
|  | gpointer | data
| ) |  |

fl_task_runner_post_callback: @task_runner: an #FlTaskRunner. @callback: callback to be scheduled @data: data to be passed to the callback

Schedules arbitrary callback to be executed on main thread. The callback will be executed in next run loop turn. This function is thread safe and may be called from any thread.

Definition at line 189 of file fl_task_runner.cc.

191 {
192 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
193 (void)locker; // unused variable
194
195 FlTaskRunnerTask* runner_task = g_new0(FlTaskRunnerTask, 1);
196 runner_task->callback = callback;
197 runner_task->callback_data = data;
198
199 self->pending_tasks = g_list_append(self->pending_tasks, runner_task);
200 fl_task_runner_tasks_did_change_locked(self);
201 }
_FlTaskRunnerTask::callback_data
gpointer callback_data
Definition: fl_task_runner.cc:36
_FlTaskRunnerTask::callback
void(* callback)(gpointer data)
Definition: fl_task_runner.cc:33

References _FlTaskRunnerTask::callback, _FlTaskRunnerTask::callback_data, and fl_task_runner_tasks_did_change_locked().

Referenced by fl_compositor_opengl_present_layers().

## ◆ fl_task_runner_post_flutter_task()

void fl_task_runner_post_flutter_task | ( | FlTaskRunner * | task_runner,
|  | FlutterTask | task,
|  | uint64_t | target_time_nanos
| ) |  |

fl_task_runner_post_flutter_task: @task_runner: an #FlTaskRunner. @task: Flutter task being scheduled @target_time_nanos: absolute time in nanoseconds

Posts a Flutter task to be executed on main thread. This function is thread safe and may be called from any thread.

Definition at line 174 of file fl_task_runner.cc.

176 {
177 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
178 (void)locker; // unused variable
179
180 FlTaskRunnerTask* runner_task = g_new0(FlTaskRunnerTask, 1);
181 runner_task->task = task;
182 runner_task->task_time_micros =
183 target_time_nanos / kMicrosecondsPerNanosecond;
184
185 self->pending_tasks = g_list_append(self->pending_tasks, runner_task);
186 fl_task_runner_tasks_did_change_locked(self);
187 }
kMicrosecondsPerNanosecond
static constexpr int kMicrosecondsPerNanosecond
Definition: fl_task_runner.cc:8
_FlTaskRunnerTask::task
FlutterTask task
Definition: fl_task_runner.cc:30

References fl_task_runner_tasks_did_change_locked(), kMicrosecondsPerNanosecond, _FlTaskRunnerTask::task, and _FlTaskRunnerTask::task_time_micros.

Referenced by fl_engine_post_task().

## ◆ fl_task_runner_process_expired_tasks_locked()

static void fl_task_runner_process_expired_tasks_locked | ( | FlTaskRunner * | self | ) |
| static

Definition at line 43 of file fl_task_runner.cc.

43 {
44 GList* expired_tasks = nullptr;
45
46 gint64 current_time = g_get_monotonic_time();
47
48 GList* l = self->pending_tasks;
49 while (l != nullptr) {
50 FlTaskRunnerTask* task = static_cast<FlTaskRunnerTask*>(l->data);
51 if (task->task_time_micros <= current_time) {
52 GList* link = l;
53 l = l->next;
54 self->pending_tasks = g_list_remove_link(self->pending_tasks, link);
55 expired_tasks = g_list_concat(expired_tasks, link);
56 } else {
57 l = l->next;
58 }
59 }
60
61 g_mutex_unlock(&self->mutex);
62
63 g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
64 if (engine != nullptr) {
65 l = expired_tasks;
66 while (l != nullptr) {
67 FlTaskRunnerTask* task = static_cast<FlTaskRunnerTask*>(l->data);
68 if (task->callback != nullptr) {
69 task->callback(task->callback_data);
70 } else {
71 fl_engine_execute_task(engine, &task->task);
72 }
73 l = l->next;
74 }
75 }
76
77 g_list_free_full(expired_tasks, g_free);
78
79 g_mutex_lock(&self->mutex);
80 }
fl_engine_execute_task
void fl_engine_execute_task(FlEngine *self, FlutterTask *task)
Definition: fl_engine.cc:1292

References _FlTaskRunnerTask::callback, _FlTaskRunnerTask::callback_data, fl_engine_execute_task(), _FlTaskRunnerTask::task, and _FlTaskRunnerTask::task_time_micros.

Referenced by fl_task_runner_block_main_thread(), and fl_task_runner_on_expired_timeout().

## ◆ fl_task_runner_release_main_thread()

void fl_task_runner_release_main_thread | ( | FlTaskRunner * | self | ) |

fl_task_runner_release_main_thread: @task_runner: an #FlTaskRunner.

Unblocks main thread. This will resume normal processing of main loop. Can be invoked from any thread.

Definition at line 224 of file fl_task_runner.cc.

224 {
225 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
226 (void)locker; // unused variable
227
228 g_return_if_fail(self->blocking_main_thread == TRUE);
229
230 self->blocking_main_thread = FALSE;
231 g_cond_signal(&self->cond);
232 }
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53

References TRUE.

Referenced by fl_compositor_opengl_unblock_main_thread().

## ◆ fl_task_runner_tasks_did_change_locked()

static void fl_task_runner_tasks_did_change_locked | ( | FlTaskRunner * | self | ) |
| static

Definition at line 119 of file fl_task_runner.cc.

119 {
120 if (self->blocking_main_thread) {
121 // Wake up blocked thread
122 g_cond_signal(&self->cond);
123 } else {
124 // Reschedule timeout
125 if (self->timeout_source_id != 0) {
126 g_source_remove(self->timeout_source_id);
127 self->timeout_source_id = 0;
128 }
129 gint64 min_time = fl_task_runner_next_task_expiration_time_locked(self);
130 if (min_time != G_MAXINT64) {
131 gint64 remaining = MAX(min_time - g_get_monotonic_time(), 0);
132 self->timeout_source_id =
133 g_timeout_add(remaining / kMillisecondsPerMicrosecond + 1,
134 fl_task_runner_on_expired_timeout, self);
135 }
136 }
137 }
kMillisecondsPerMicrosecond
static constexpr int kMillisecondsPerMicrosecond
Definition: fl_task_runner.cc:9
fl_task_runner_on_expired_timeout
static gboolean fl_task_runner_on_expired_timeout(gpointer data)
Definition: fl_task_runner.cc:86

References fl_task_runner_next_task_expiration_time_locked(), fl_task_runner_on_expired_timeout(), and kMillisecondsPerMicrosecond.

Referenced by fl_task_runner_block_main_thread(), fl_task_runner_on_expired_timeout(), fl_task_runner_post_callback(), and fl_task_runner_post_flutter_task().

## Variable Documentation

## ◆ kMicrosecondsPerNanosecond

constexpr int kMicrosecondsPerNanosecond = 1000
| static constexpr

Definition at line 8 of file fl_task_runner.cc.

Referenced by fl_task_runner_post_flutter_task().

## ◆ kMillisecondsPerMicrosecond

constexpr int kMillisecondsPerMicrosecond = 1000
| static constexpr

Definition at line 9 of file fl_task_runner.cc.

Referenced by fl_task_runner_tasks_did_change_locked().