| 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_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 179 of file fl_task_runner.cc.

179 {
180 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
181 (void)locker; // unused variable
182
183 g_return_if_fail(self->blocking_main_thread == FALSE);
184
185 g_object_ref(self);
186
187 self->blocking_main_thread = true;
188 while (self->blocking_main_thread) {
189 g_cond_wait_until(&self->cond, &self->mutex,
190 fl_task_runner_next_task_expiration_time_locked(self));
191 fl_task_runner_process_expired_tasks_locked(self);
192 }
193
194 // Tasks might have changed in the meanwhile, reschedule timeout
195 fl_task_runner_tasks_did_change_locked(self);
196
197 g_object_unref(self);
198 }
g_autoptr
g_autoptr(GMutexLocker) locker
self
g_cond_signal & self
Definition: fl_compositor_software.cc:67
fl_task_runner_process_expired_tasks_locked
static void fl_task_runner_process_expired_tasks_locked(FlTaskRunner *self)
Definition: fl_task_runner.cc:37
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:97
fl_task_runner_tasks_did_change_locked
static void fl_task_runner_tasks_did_change_locked(FlTaskRunner *self)
Definition: fl_task_runner.cc:109

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

## ◆ fl_task_runner_class_init()

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

Definition at line 148 of file fl_task_runner.cc.

148 {
149 G_OBJECT_CLASS(klass)->dispose = fl_task_runner_dispose;
150 }
fl_task_runner_dispose
void fl_task_runner_dispose(GObject *object)
Definition: fl_task_runner.cc:129

References fl_task_runner_dispose().

## ◆ fl_task_runner_dispose()

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

Definition at line 129 of file fl_task_runner.cc.

129 {
130 FlTaskRunner* self = FL_TASK_RUNNER(object);
131
132 // this should never happen because the task runner is retained while blocking
133 // main thread
134 g_assert(!self->blocking_main_thread);
135
136 g_weak_ref_clear(&self->engine);
137 g_mutex_clear(&self->mutex);
138 g_cond_clear(&self->cond);
139
140 g_list_free_full(self->pending_tasks, g_free);
141 if (self->timeout_source_id != 0) {
142 g_source_remove(self->timeout_source_id);
143 }
144
145 G_OBJECT_CLASS(fl_task_runner_parent_class)->dispose(object);
146 }

References self.

Referenced by fl_task_runner_class_init().

## ◆ fl_task_runner_init()

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

Definition at line 152 of file fl_task_runner.cc.

152 {
153 g_mutex_init(&self->mutex);
154 g_cond_init(&self->cond);
155 }

References self.

## ◆ 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 157 of file fl_task_runner.cc.

157 {
158 FlTaskRunner* self =
159 FL_TASK_RUNNER(g_object_new(fl_task_runner_get_type(), nullptr));
160 g_weak_ref_init(&self->engine, G_OBJECT(engine));
161 return self;
162 }

References self.

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 97 of file fl_task_runner.cc.

98 {
99 gint64 min_time = G_MAXINT64;
100 GList* l = self->pending_tasks;
101 while (l != nullptr) {
102 FlTaskRunnerTask* task = static_cast<FlTaskRunnerTask*>(l->data);
103 min_time = MIN(min_time, task->task_time_micros);
104 l = l->next;
105 }
106 return min_time;
107 }
_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 76 of file fl_task_runner.cc.

76 {
77 FlTaskRunner* self = FL_TASK_RUNNER(data);
78
79 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
80 (void)locker; // unused variable
81
82 g_object_ref(self);
83
84 self->timeout_source_id = 0;
85 fl_task_runner_process_expired_tasks_locked(self);
86
87 // reschedule timeout
88 fl_task_runner_tasks_did_change_locked(self);
89
90 g_object_unref(self);
91
92 return FALSE;
93 }

References fl_task_runner_process_expired_tasks_locked(), fl_task_runner_tasks_did_change_locked(), g_autoptr(), and self.

Referenced by fl_task_runner_tasks_did_change_locked().

## ◆ 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 164 of file fl_task_runner.cc.

166 {
167 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
168 (void)locker; // unused variable
169
170 FlTaskRunnerTask* runner_task = g_new0(FlTaskRunnerTask, 1);
171 runner_task->task = task;
172 runner_task->task_time_micros =
173 target_time_nanos / kMicrosecondsPerNanosecond;
174
175 self->pending_tasks = g_list_append(self->pending_tasks, runner_task);
176 fl_task_runner_tasks_did_change_locked(self);
177 }
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(), g_autoptr(), kMicrosecondsPerNanosecond, self, _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 37 of file fl_task_runner.cc.

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

References fl_engine_execute_task(), g_autoptr(), self, _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 200 of file fl_task_runner.cc.

200 {
201 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
202 (void)locker; // unused variable
203
204 g_return_if_fail(self->blocking_main_thread == TRUE);
205
206 self->blocking_main_thread = FALSE;
207 g_cond_signal(&self->cond);
208 }
TRUE
return TRUE
Definition: fl_compositor_software.cc:69

References g_autoptr(), self, and TRUE.

## ◆ fl_task_runner_tasks_did_change_locked()

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

Definition at line 109 of file fl_task_runner.cc.

109 {
110 if (self->blocking_main_thread) {
111 // Wake up blocked thread
112 g_cond_signal(&self->cond);
113 } else {
114 // Reschedule timeout
115 if (self->timeout_source_id != 0) {
116 g_source_remove(self->timeout_source_id);
117 self->timeout_source_id = 0;
118 }
119 gint64 min_time = fl_task_runner_next_task_expiration_time_locked(self);
120 if (min_time != G_MAXINT64) {
121 gint64 remaining = MAX(min_time - g_get_monotonic_time(), 0);
122 self->timeout_source_id =
123 g_timeout_add(remaining / kMillisecondsPerMicrosecond + 1,
124 fl_task_runner_on_expired_timeout, self);
125 }
126 }
127 }
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:76

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

Referenced by fl_task_runner_block_main_thread(), fl_task_runner_on_expired_timeout(), 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().