| // Copyright 2013 The Flutter Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "flutter/shell/platform/embedder/embedder_task_runner.h" | |
| #include "flutter/fml/message_loop_impl.h" | |
| #include "flutter/fml/message_loop_task_queues.h" | |
| namespace flutter { | |
| EmbedderTaskRunner::EmbedderTaskRunner(DispatchTable table, | |
| size_t embedder_identifier) | |
| : TaskRunner(nullptr /* loop implemenation*/), | |
| embedder_identifier_(embedder_identifier), | |
| dispatch_table_(std::move(table)), | |
| placeholder_id_( | |
| fml::MessageLoopTaskQueues::GetInstance()->CreateTaskQueue()) { | |
| FML_DCHECK(dispatch_table_.post_task_callback); | |
| FML_DCHECK(dispatch_table_.runs_task_on_current_thread_callback); | |
| } | |
| EmbedderTaskRunner::~EmbedderTaskRunner() = default; | |
| size_t EmbedderTaskRunner::GetEmbedderIdentifier() const { | |
| return embedder_identifier_; | |
| } | |
| void EmbedderTaskRunner::PostTask(const fml::closure& task) { | |
| PostTaskForTime(task, fml::TimePoint::Now()); | |
| } | |
| void EmbedderTaskRunner::PostTaskForTime(const fml::closure& task, | |
| fml::TimePoint target_time) { | |
| if (!task) { | |
| return; | |
| } | |
| uint64_t baton = 0; | |
| { | |
| // Release the lock before the jump via the dispatch table. | |
| std::scoped_lock lock(tasks_mutex_); | |
| baton = ++last_baton_; | |
| pending_tasks_[baton] = task; | |
| } | |
| dispatch_table_.post_task_callback(this, baton, target_time); | |
| } | |
| void EmbedderTaskRunner::PostDelayedTask(const fml::closure& task, | |
| fml::TimeDelta delay) { | |
| PostTaskForTime(task, fml::TimePoint::Now() + delay); | |
| } | |
| bool EmbedderTaskRunner::RunsTasksOnCurrentThread() { | |
| return dispatch_table_.runs_task_on_current_thread_callback(); | |
| } | |
| bool EmbedderTaskRunner::PostTask(uint64_t baton) { | |
| fml::closure task; | |
| { | |
| std::scoped_lock lock(tasks_mutex_); | |
| auto found = pending_tasks_.find(baton); | |
| if (found == pending_tasks_.end()) { | |
| FML_LOG(ERROR) << "Embedder attempted to post an unknown task."; | |
| return false; | |
| } | |
| task = found->second; | |
| pending_tasks_.erase(found); | |
| // Let go of the tasks mutex befor executing the task. | |
| } | |
| FML_DCHECK(task); | |
| task(); | |
| return true; | |
| } | |
| // |fml::TaskRunner| | |
| fml::TaskQueueId EmbedderTaskRunner::GetTaskQueueId() { | |
| return placeholder_id_; | |
| } | |
| } // namespace flutter |