• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
9 namespace flutter {
10 
EmbedderTaskRunner(DispatchTable table)11 EmbedderTaskRunner::EmbedderTaskRunner(DispatchTable table)
12     : TaskRunner(nullptr /* loop implemenation*/),
13       dispatch_table_(std::move(table)) {
14   FML_DCHECK(dispatch_table_.post_task_callback);
15   FML_DCHECK(dispatch_table_.runs_task_on_current_thread_callback);
16 }
17 
18 EmbedderTaskRunner::~EmbedderTaskRunner() = default;
19 
PostTask(fml::closure task)20 void EmbedderTaskRunner::PostTask(fml::closure task) {
21   PostTaskForTime(task, fml::TimePoint::Now());
22 }
23 
PostTaskForTime(fml::closure task,fml::TimePoint target_time)24 void EmbedderTaskRunner::PostTaskForTime(fml::closure task,
25                                          fml::TimePoint target_time) {
26   if (!task) {
27     return;
28   }
29 
30   uint64_t baton = 0;
31 
32   {
33     // Release the lock before the jump via the dispatch table.
34     std::scoped_lock lock(tasks_mutex_);
35     baton = ++last_baton_;
36     pending_tasks_[baton] = task;
37   }
38 
39   dispatch_table_.post_task_callback(this, baton, target_time);
40 }
41 
PostDelayedTask(fml::closure task,fml::TimeDelta delay)42 void EmbedderTaskRunner::PostDelayedTask(fml::closure task,
43                                          fml::TimeDelta delay) {
44   PostTaskForTime(task, fml::TimePoint::Now() + delay);
45 }
46 
RunsTasksOnCurrentThread()47 bool EmbedderTaskRunner::RunsTasksOnCurrentThread() {
48   return dispatch_table_.runs_task_on_current_thread_callback();
49 }
50 
PostTask(uint64_t baton)51 bool EmbedderTaskRunner::PostTask(uint64_t baton) {
52   fml::closure task;
53 
54   {
55     std::scoped_lock lock(tasks_mutex_);
56     auto found = pending_tasks_.find(baton);
57     if (found == pending_tasks_.end()) {
58       FML_LOG(ERROR) << "Embedder attempted to post an unknown task.";
59       return false;
60     }
61     task = found->second;
62     pending_tasks_.erase(found);
63 
64     // Let go of the tasks mutex befor executing the task.
65   }
66 
67   FML_DCHECK(task);
68   task();
69   return true;
70 }
71 
72 }  // namespace flutter
73