Flutter Linux Embedder
fl_task_runner.cc File Reference

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_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

◆ 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 176 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  g_return_if_fail(self->blocking_main_thread == FALSE);
181 
182  g_object_ref(self);
183 
184  self->blocking_main_thread = true;
185  while (self->blocking_main_thread) {
186  g_cond_wait_until(&self->cond, &self->mutex,
189  }
190 
191  // Tasks might have changed in the meanwhile, reschedule timeout
193 
194  g_object_unref(self);
195 }

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_renderer_wait_for_frame().

◆ fl_task_runner_class_init()

static void fl_task_runner_class_init ( FlTaskRunnerClass *  klass)
static

Definition at line 145 of file fl_task_runner.cc.

145  {
146  G_OBJECT_CLASS(klass)->dispose = fl_task_runner_dispose;
147 }

References fl_task_runner_dispose().

◆ fl_task_runner_dispose()

void fl_task_runner_dispose ( GObject *  object)

Definition at line 126 of file fl_task_runner.cc.

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

Referenced by fl_task_runner_class_init().

◆ fl_task_runner_init()

static void fl_task_runner_init ( FlTaskRunner *  self)
static

Definition at line 149 of file fl_task_runner.cc.

149  {
150  g_mutex_init(&self->mutex);
151  g_cond_init(&self->cond);
152 }

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

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

Referenced by fl_engine_start().

◆ fl_task_runner_next_task_expiration_time_locked()

static gint64 fl_task_runner_next_task_expiration_time_locked ( FlTaskRunner *  self)
static

Definition at line 94 of file fl_task_runner.cc.

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

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

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

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

163  {
164  g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
165  (void)locker; // unused variable
166 
167  FlTaskRunnerTask* runner_task = g_new0(FlTaskRunnerTask, 1);
168  runner_task->task = task;
169  runner_task->task_time_micros =
170  target_time_nanos / kMicrosecondsPerNanosecond;
171 
172  self->pending_tasks = g_list_append(self->pending_tasks, runner_task);
174 }

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 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  g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
55  if (engine != nullptr) {
56  l = expired_tasks;
57  while (l != nullptr) {
58  FlTaskRunnerTask* task = static_cast<FlTaskRunnerTask*>(l->data);
59  fl_engine_execute_task(engine, &task->task);
60  l = l->next;
61  }
62  }
63 
64  g_list_free_full(expired_tasks, g_free);
65 
66  g_mutex_lock(&self->mutex);
67 }

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

197  {
198  g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
199  (void)locker; // unused variable
200 
201  g_return_if_fail(self->blocking_main_thread == TRUE);
202 
203  self->blocking_main_thread = FALSE;
204  g_cond_signal(&self->cond);
205 }

References TRUE.

Referenced by fl_renderer_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 106 of file fl_task_runner.cc.

106  {
107  if (self->blocking_main_thread) {
108  // Wake up blocked thread
109  g_cond_signal(&self->cond);
110  } else {
111  // Reschedule timeout
112  if (self->timeout_source_id != 0) {
113  g_source_remove(self->timeout_source_id);
114  self->timeout_source_id = 0;
115  }
116  gint64 min_time = fl_task_runner_next_task_expiration_time_locked(self);
117  if (min_time != G_MAXINT64) {
118  gint64 remaining = MAX(min_time - g_get_monotonic_time(), 0);
119  self->timeout_source_id =
120  g_timeout_add(remaining / kMillisecondsPerMicrosecond + 1,
122  }
123  }
124 }

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(), and fl_task_runner_post_task().

Variable Documentation

◆ kMicrosecondsPerNanosecond

constexpr int kMicrosecondsPerNanosecond = 1000
staticconstexpr

Definition at line 8 of file fl_task_runner.cc.

Referenced by fl_task_runner_post_task().

◆ kMillisecondsPerMicrosecond

constexpr int kMillisecondsPerMicrosecond = 1000
staticconstexpr

Definition at line 9 of file fl_task_runner.cc.

Referenced by fl_task_runner_tasks_did_change_locked().

kMicrosecondsPerNanosecond
static constexpr int kMicrosecondsPerNanosecond
Definition: fl_task_runner.cc:8
_FlTaskRunnerTask::task_time_micros
gint64 task_time_micros
Definition: fl_task_runner.cc:26
fl_task_runner_process_expired_tasks_locked
static void fl_task_runner_process_expired_tasks_locked(FlTaskRunner *self)
Definition: fl_task_runner.cc:34
fl_task_runner_dispose
void fl_task_runner_dispose(GObject *object)
Definition: fl_task_runner.cc:126
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:94
fl_task_runner_on_expired_timeout
static gboolean fl_task_runner_on_expired_timeout(gpointer data)
Definition: fl_task_runner.cc:73
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
kMillisecondsPerMicrosecond
static constexpr int kMillisecondsPerMicrosecond
Definition: fl_task_runner.cc:9
fl_task_runner_tasks_did_change_locked
static void fl_task_runner_tasks_did_change_locked(FlTaskRunner *self)
Definition: fl_task_runner.cc:106
fl_engine_execute_task
void fl_engine_execute_task(FlEngine *self, FlutterTask *task)
Definition: fl_engine.cc:929
_FlTaskRunnerTask::task
FlutterTask task
Definition: fl_task_runner.cc:27
_FlTaskRunnerTask
Definition: fl_task_runner.cc:24