• 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 #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