Flutter Engine
The Flutter Engine
message_loop_impl.cc
Go to the documentation of this file.
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#define FML_USED_ON_EMBEDDER
6
7#include "flutter/fml/message_loop_impl.h"
8
9#include <algorithm>
10#include <vector>
11
12#include "flutter/fml/build_config.h"
13#include "flutter/fml/logging.h"
14
15#if FML_OS_MACOSX
16#include "flutter/fml/platform/darwin/message_loop_darwin.h"
17#elif FML_OS_ANDROID
18#include "flutter/fml/platform/android/message_loop_android.h"
19#elif OS_FUCHSIA
20#include "flutter/fml/platform/fuchsia/message_loop_fuchsia.h"
21#elif FML_OS_LINUX
22#include "flutter/fml/platform/linux/message_loop_linux.h"
23#elif FML_OS_WIN
24#include "flutter/fml/platform/win/message_loop_win.h"
25#endif
26
27namespace fml {
28
30#if FML_OS_MACOSX
31 return fml::MakeRefCounted<MessageLoopDarwin>();
32#elif FML_OS_ANDROID
33 return fml::MakeRefCounted<MessageLoopAndroid>();
34#elif OS_FUCHSIA
35 return fml::MakeRefCounted<MessageLoopFuchsia>();
36#elif FML_OS_LINUX
37 return fml::MakeRefCounted<MessageLoopLinux>();
38#elif FML_OS_WIN
39 return fml::MakeRefCounted<MessageLoopWin>();
40#else
41 return nullptr;
42#endif
43}
44
46 : task_queue_(MessageLoopTaskQueues::GetInstance()),
47 queue_id_(task_queue_->CreateTaskQueue()),
48 terminated_(false) {
49 task_queue_->SetWakeable(queue_id_, this);
50}
51
53 task_queue_->Dispose(queue_id_);
54}
55
57 fml::TimePoint target_time) {
58 FML_DCHECK(task != nullptr);
59 if (terminated_) {
60 // If the message loop has already been terminated, PostTask should destruct
61 // |task| synchronously within this function.
62 return;
63 }
64 task_queue_->RegisterTask(queue_id_, task, target_time);
65}
66
68 const fml::closure& callback) {
69 FML_DCHECK(callback != nullptr);
70 FML_DCHECK(MessageLoop::GetCurrent().GetLoopImpl().get() == this)
71 << "Message loop task observer must be added on the same thread as the "
72 "loop.";
73 if (callback != nullptr) {
74 task_queue_->AddTaskObserver(queue_id_, key, callback);
75 } else {
76 FML_LOG(ERROR) << "Tried to add a null TaskObserver.";
77 }
78}
79
81 FML_DCHECK(MessageLoop::GetCurrent().GetLoopImpl().get() == this)
82 << "Message loop task observer must be removed from the same thread as "
83 "the loop.";
84 task_queue_->RemoveTaskObserver(queue_id_, key);
85}
86
88 if (terminated_) {
89 // Message loops may be run only once.
90 return;
91 }
92
93 // Allow the implementation to do its thing.
94 Run();
95
96 // The loop may have been implicitly terminated. This can happen if the
97 // implementation supports termination via platform specific APIs or just
98 // error conditions. Set the terminated flag manually.
99 terminated_ = true;
100
101 // The message loop is shutting down. Check if there are expired tasks. This
102 // is the last chance for expired tasks to be serviced. Make sure the
103 // terminated flag is already set so we don't accrue additional tasks now.
105
106 // When the message loop is in the process of shutting down, pending tasks
107 // should be destructed on the message loop's thread. We have just returned
108 // from the implementations |Run| method which we know is on the correct
109 // thread. Drop all pending tasks on the floor.
110 task_queue_->DisposeTasks(queue_id_);
111}
112
114 terminated_ = true;
115 Terminate();
116}
117
118void MessageLoopImpl::FlushTasks(FlushType type) {
119 const auto now = fml::TimePoint::Now();
120 fml::closure invocation;
121 do {
122 invocation = task_queue_->GetNextTaskToRun(queue_id_, now);
123 if (!invocation) {
124 break;
125 }
126 invocation();
127 std::vector<fml::closure> observers =
128 task_queue_->GetObserversToNotify(queue_id_);
129 for (const auto& observer : observers) {
130 observer();
131 }
132 if (type == FlushType::kSingle) {
133 break;
134 }
135 } while (invocation);
136}
137
139 FlushTasks(FlushType::kAll);
140}
141
143 FlushTasks(FlushType::kSingle);
144}
145
147 return queue_id_;
148}
149
150} // namespace fml
GLenum type
virtual TaskQueueId GetTaskQueueId() const
virtual void Terminate()=0
void AddTaskObserver(intptr_t key, const fml::closure &callback)
void PostTask(const fml::closure &task, fml::TimePoint target_time)
void RemoveTaskObserver(intptr_t key)
static fml::RefPtr< MessageLoopImpl > Create()
virtual void Run()=0
fml::closure GetNextTaskToRun(TaskQueueId queue_id, fml::TimePoint from_time)
void DisposeTasks(TaskQueueId queue_id)
void RegisterTask(TaskQueueId queue_id, const fml::closure &task, fml::TimePoint target_time, fml::TaskSourceGrade task_source_grade=fml::TaskSourceGrade::kUnspecified)
std::vector< fml::closure > GetObserversToNotify(TaskQueueId queue_id) const
void AddTaskObserver(TaskQueueId queue_id, intptr_t key, const fml::closure &callback)
void RemoveTaskObserver(TaskQueueId queue_id, intptr_t key)
void SetWakeable(TaskQueueId queue_id, fml::Wakeable *wakeable)
void Dispose(TaskQueueId queue_id)
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
Definition: message_loop.cc:19
static TimePoint Now()
Definition: time_point.cc:49
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
#define FML_LOG(severity)
Definition: logging.h:82
#define FML_DCHECK(condition)
Definition: logging.h:103
Definition: ascii_trie.cc:9
std::function< void()> closure
Definition: closure.h:14
const myers::Point & get(const myers::Segment &)
#define ERROR(message)
Definition: elf_loader.cc:260