44 GList* expired_tasks =
nullptr;
46 gint64 current_time = g_get_monotonic_time();
48 GList* l =
self->pending_tasks;
49 while (l !=
nullptr) {
54 self->pending_tasks = g_list_remove_link(self->pending_tasks, link);
55 expired_tasks = g_list_concat(expired_tasks, link);
61 g_mutex_unlock(&self->mutex);
63 g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
64 if (engine !=
nullptr) {
66 while (l !=
nullptr) {
77 g_list_free_full(expired_tasks, g_free);
79 g_mutex_lock(&self->mutex);
87 FlTaskRunner*
self = FL_TASK_RUNNER(data);
89 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
94 self->timeout_source_id = 0;
100 g_object_unref(
self);
108 FlTaskRunner*
self) {
109 gint64 min_time = G_MAXINT64;
110 GList* l =
self->pending_tasks;
111 while (l !=
nullptr) {
120 if (self->blocking_main_thread) {
122 g_cond_signal(&self->cond);
125 if (self->timeout_source_id != 0) {
126 g_source_remove(self->timeout_source_id);
127 self->timeout_source_id = 0;
130 if (min_time != G_MAXINT64) {
131 gint64 remaining = MAX(min_time - g_get_monotonic_time(), 0);
132 self->timeout_source_id =
140 FlTaskRunner*
self = FL_TASK_RUNNER(
object);
144 g_assert(!self->blocking_main_thread);
146 g_weak_ref_clear(&self->engine);
147 g_mutex_clear(&self->mutex);
148 g_cond_clear(&self->cond);
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);
155 G_OBJECT_CLASS(fl_task_runner_parent_class)->dispose(
object);
163 g_mutex_init(&self->mutex);
164 g_cond_init(&self->cond);
169 FL_TASK_RUNNER(g_object_new(fl_task_runner_get_type(),
nullptr));
170 g_weak_ref_init(&self->engine, G_OBJECT(engine));
176 uint64_t target_time_nanos) {
177 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
181 runner_task->
task = task;
185 self->pending_tasks = g_list_append(self->pending_tasks, runner_task);
190 void (*callback)(gpointer data),
192 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
199 self->pending_tasks = g_list_append(self->pending_tasks, runner_task);
204 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
207 g_return_if_fail(self->blocking_main_thread == FALSE);
211 self->blocking_main_thread =
true;
212 while (self->blocking_main_thread) {
213 g_cond_wait_until(&self->cond, &self->mutex,
221 g_object_unref(
self);
225 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->mutex);
228 g_return_if_fail(self->blocking_main_thread ==
TRUE);
230 self->blocking_main_thread = FALSE;
231 g_cond_signal(&self->cond);
G_DEFINE_TYPE(FlBasicMessageChannelResponseHandle, fl_basic_message_channel_response_handle, G_TYPE_OBJECT) static void fl_basic_message_channel_response_handle_dispose(GObject *object)
void fl_engine_execute_task(FlEngine *self, FlutterTask *task)
void fl_task_runner_dispose(GObject *object)
void fl_task_runner_post_callback(FlTaskRunner *self, void(*callback)(gpointer data), gpointer data)
static void fl_task_runner_process_expired_tasks_locked(FlTaskRunner *self)
void fl_task_runner_post_flutter_task(FlTaskRunner *self, FlutterTask task, uint64_t target_time_nanos)
struct _FlTaskRunnerTask FlTaskRunnerTask
static gint64 fl_task_runner_next_task_expiration_time_locked(FlTaskRunner *self)
void fl_task_runner_release_main_thread(FlTaskRunner *self)
static constexpr int kMillisecondsPerMicrosecond
static void fl_task_runner_class_init(FlTaskRunnerClass *klass)
static void fl_task_runner_tasks_did_change_locked(FlTaskRunner *self)
void fl_task_runner_block_main_thread(FlTaskRunner *self)
static gboolean fl_task_runner_on_expired_timeout(gpointer data)
static constexpr int kMicrosecondsPerNanosecond
FlTaskRunner * fl_task_runner_new(FlEngine *engine)
static void fl_task_runner_init(FlTaskRunner *self)
gboolean blocking_main_thread
void(* callback)(gpointer data)