blob: abbc340db0faf126cb06e716727b186fd7744759 [file] [log] [blame]
// 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