Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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)
 
static void engine_weak_notify_cb (gpointer user_data, GObject *where_the_object_was)
 
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_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

Function Documentation

◆ engine_weak_notify_cb()

static void engine_weak_notify_cb ( gpointer  user_data,
GObject *  where_the_object_was 
)
static

Definition at line 123 of file fl_task_runner.cc.

124 {
125 FlTaskRunner* self = FL_TASK_RUNNER(user_data);
126 self->engine = nullptr;
127}

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

184 {
185 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
186 (void)locker; // unused variable
187
188 g_return_if_fail(self->blocking_main_thread == FALSE);
189
190 g_object_ref(self);
191
192 self->blocking_main_thread = true;
193 while (self->blocking_main_thread) {
194 g_cond_wait_until(&self->cond, &self->mutex,
197 }
198
199 // Tasks might have changed in the meanwhile, reschedule timeout
201
202 g_object_unref(self);
203}
static void fl_task_runner_process_expired_tasks_locked(FlTaskRunner *self)
static gint64 fl_task_runner_next_task_expiration_time_locked(FlTaskRunner *self)
static void fl_task_runner_tasks_did_change_locked(FlTaskRunner *self)
return FALSE

◆ fl_task_runner_class_init()

static void fl_task_runner_class_init ( FlTaskRunnerClass *  klass)
static

Definition at line 152 of file fl_task_runner.cc.

152 {
153 G_OBJECT_CLASS(klass)->dispose = fl_task_runner_dispose;
154}
void fl_task_runner_dispose(GObject *object)

◆ 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 if (self->engine != nullptr) {
137 g_object_weak_unref(G_OBJECT(self->engine), engine_weak_notify_cb, self);
138 self->engine = nullptr;
139 }
140
141 g_mutex_clear(&self->mutex);
142 g_cond_clear(&self->cond);
143
144 g_list_free_full(self->pending_tasks, g_free);
145 if (self->timeout_source_id != 0) {
146 g_source_remove(self->timeout_source_id);
147 }
148
149 G_OBJECT_CLASS(fl_task_runner_parent_class)->dispose(object);
150}
static void engine_weak_notify_cb(gpointer user_data, GObject *where_the_object_was)

◆ fl_task_runner_init()

static void fl_task_runner_init ( FlTaskRunner *  self)
static

Definition at line 156 of file fl_task_runner.cc.

156 {
157 g_mutex_init(&self->mutex);
158 g_cond_init(&self->cond);
159}

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

161 {
162 FlTaskRunner* res =
163 FL_TASK_RUNNER(g_object_new(fl_task_runner_get_type(), nullptr));
164 res->engine = engine;
165 g_object_weak_ref(G_OBJECT(engine), engine_weak_notify_cb, res);
166 return res;
167}
FlutterEngine engine
Definition main.cc:68

◆ fl_task_runner_next_task_expiration_time_locked()

static gint64 fl_task_runner_next_task_expiration_time_locked ( FlTaskRunner *  self)
static

Definition at line 91 of file fl_task_runner.cc.

92 {
93 gint64 min_time = G_MAXINT64;
94 GList* l = self->pending_tasks;
95 while (l != nullptr) {
96 FlTaskRunnerTask* task = static_cast<FlTaskRunnerTask*>(l->data);
97 min_time = MIN(min_time, task->task_time_micros);
98 l = l->next;
99 }
100 return min_time;
101}

◆ fl_task_runner_on_expired_timeout()

static gboolean fl_task_runner_on_expired_timeout ( gpointer  data)
static

Definition at line 70 of file fl_task_runner.cc.

70 {
71 FlTaskRunner* self = FL_TASK_RUNNER(data);
72
73 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
74 (void)locker; // unused variable
75
76 g_object_ref(self);
77
78 self->timeout_source_id = 0;
80
81 // reschedule timeout
83
84 g_object_unref(self);
85
86 return FALSE;
87}

◆ fl_task_runner_post_task()

void fl_task_runner_post_task ( FlTaskRunner *  task_runner,
FlutterTask  task,
uint64_t  target_time_nanos 
)

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

171 {
172 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
173 (void)locker; // unused variable
174
175 FlTaskRunnerTask* runner_task = g_new0(FlTaskRunnerTask, 1);
176 runner_task->task = task;
177 runner_task->task_time_micros =
178 target_time_nanos / kMicrosecondsPerNanosecond;
179
180 self->pending_tasks = g_list_append(self->pending_tasks, runner_task);
182}
static constexpr int kMicrosecondsPerNanosecond

◆ fl_task_runner_process_expired_tasks_locked()

static void fl_task_runner_process_expired_tasks_locked ( FlTaskRunner *  self)
static

Definition at line 34 of file fl_task_runner.cc.

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

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

205 {
206 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
207 (void)locker; // unused variable
208
209 g_return_if_fail(self->blocking_main_thread == TRUE);
210
211 self->blocking_main_thread = FALSE;
212 g_cond_signal(&self->cond);
213}

◆ fl_task_runner_tasks_did_change_locked()

static void fl_task_runner_tasks_did_change_locked ( FlTaskRunner *  self)
static

Definition at line 103 of file fl_task_runner.cc.

103 {
104 if (self->blocking_main_thread) {
105 // Wake up blocked thread
106 g_cond_signal(&self->cond);
107 } else {
108 // Reschedule timeout
109 if (self->timeout_source_id != 0) {
110 g_source_remove(self->timeout_source_id);
111 self->timeout_source_id = 0;
112 }
114 if (min_time != G_MAXINT64) {
115 gint64 remaining = MAX(min_time - g_get_monotonic_time(), 0);
116 self->timeout_source_id =
117 g_timeout_add(remaining / kMillisecondsPerMicrosecond + 1,
119 }
120 }
121}
static constexpr int kMillisecondsPerMicrosecond
static gboolean fl_task_runner_on_expired_timeout(gpointer data)

Variable Documentation

◆ kMicrosecondsPerNanosecond

constexpr int kMicrosecondsPerNanosecond = 1000
staticconstexpr

Definition at line 8 of file fl_task_runner.cc.

◆ kMillisecondsPerMicrosecond

constexpr int kMillisecondsPerMicrosecond = 1000
staticconstexpr

Definition at line 9 of file fl_task_runner.cc.