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