1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "flutter/shell/platform/embedder/embedder_task_runner.h"
6
7 #include "flutter/fml/message_loop_impl.h"
8 #include "flutter/fml/message_loop_task_queues.h"
9
10 namespace flutter {
11
EmbedderTaskRunner(DispatchTable table,size_t embedder_identifier)12 EmbedderTaskRunner::EmbedderTaskRunner(DispatchTable table,
13 size_t embedder_identifier)
14 : TaskRunner(nullptr /* loop implemenation*/),
15 embedder_identifier_(embedder_identifier),
16 dispatch_table_(std::move(table)),
17 placeholder_id_(fml::MessageLoopTaskQueues::GetInstance()->CreateTaskQueue()) {
18 FML_DCHECK(dispatch_table_.post_task_callback);
19 FML_DCHECK(dispatch_table_.runs_task_on_current_thread_callback);
20 }
21
22 EmbedderTaskRunner::~EmbedderTaskRunner() = default;
23
GetEmbedderIdentifier() const24 size_t EmbedderTaskRunner::GetEmbedderIdentifier() const {
25 return embedder_identifier_;
26 }
27
PostTask(fml::closure task)28 void EmbedderTaskRunner::PostTask(fml::closure task) {
29 PostTaskForTime(task, fml::TimePoint::Now());
30 }
31
PostTaskForTime(fml::closure task,fml::TimePoint target_time)32 void EmbedderTaskRunner::PostTaskForTime(fml::closure task,
33 fml::TimePoint target_time) {
34 if (!task) {
35 return;
36 }
37
38 uint64_t baton = 0;
39
40 {
41 // Release the lock before the jump via the dispatch table.
42 std::scoped_lock lock(tasks_mutex_);
43 baton = ++last_baton_;
44 pending_tasks_[baton] = task;
45 }
46
47 dispatch_table_.post_task_callback(this, baton, target_time);
48 }
49
PostDelayedTask(fml::closure task,fml::TimeDelta delay)50 void EmbedderTaskRunner::PostDelayedTask(fml::closure task,
51 fml::TimeDelta delay) {
52 PostTaskForTime(task, fml::TimePoint::Now() + delay);
53 }
54
RunsTasksOnCurrentThread()55 bool EmbedderTaskRunner::RunsTasksOnCurrentThread() {
56 return dispatch_table_.runs_task_on_current_thread_callback();
57 }
58
PostTask(uint64_t baton)59 bool EmbedderTaskRunner::PostTask(uint64_t baton) {
60 fml::closure task;
61
62 {
63 std::scoped_lock lock(tasks_mutex_);
64 auto found = pending_tasks_.find(baton);
65 if (found == pending_tasks_.end()) {
66 FML_LOG(ERROR) << "Embedder attempted to post an unknown task.";
67 return false;
68 }
69 task = found->second;
70 pending_tasks_.erase(found);
71
72 // Let go of the tasks mutex befor executing the task.
73 }
74
75 FML_DCHECK(task);
76 task();
77 return true;
78 }
79
GetTaskQueueId()80 fml::TaskQueueId EmbedderTaskRunner::GetTaskQueueId() {
81 return placeholder_id_;
82 }
83
84 } // namespace flutter
85