2018-11-07 12:24:35 -08:00
|
|
|
// Copyright 2013 The Flutter Authors. All rights reserved.
|
2017-03-20 13:41:41 -07:00
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
2018-04-13 13:48:15 -07:00
|
|
|
#define FML_USED_ON_EMBEDDER
|
|
|
|
|
|
2017-03-20 13:41:41 -07:00
|
|
|
#include "flutter/fml/message_loop_impl.h"
|
|
|
|
|
|
2017-03-23 15:29:33 -07:00
|
|
|
#include <algorithm>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
2018-04-21 20:50:03 -07:00
|
|
|
#include "flutter/fml/build_config.h"
|
2018-05-18 15:43:49 -07:00
|
|
|
#include "flutter/fml/logging.h"
|
2017-03-29 13:04:25 -07:00
|
|
|
#include "flutter/fml/trace_event.h"
|
2017-03-20 13:41:41 -07:00
|
|
|
|
|
|
|
|
#if OS_MACOSX
|
|
|
|
|
#include "flutter/fml/platform/darwin/message_loop_darwin.h"
|
|
|
|
|
#elif OS_ANDROID
|
|
|
|
|
#include "flutter/fml/platform/android/message_loop_android.h"
|
2019-11-25 14:16:50 -08:00
|
|
|
#elif OS_FUCHSIA
|
|
|
|
|
#include "flutter/fml/platform/fuchsia/message_loop_fuchsia.h"
|
2017-03-20 13:41:41 -07:00
|
|
|
#elif OS_LINUX
|
|
|
|
|
#include "flutter/fml/platform/linux/message_loop_linux.h"
|
2017-04-04 12:48:11 -07:00
|
|
|
#elif OS_WIN
|
|
|
|
|
#include "flutter/fml/platform/win/message_loop_win.h"
|
2017-03-20 13:41:41 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
namespace fml {
|
|
|
|
|
|
2018-07-26 12:49:34 -07:00
|
|
|
fml::RefPtr<MessageLoopImpl> MessageLoopImpl::Create() {
|
2018-04-13 13:48:15 -07:00
|
|
|
#if OS_MACOSX
|
2018-07-26 12:49:34 -07:00
|
|
|
return fml::MakeRefCounted<MessageLoopDarwin>();
|
2018-04-13 13:48:15 -07:00
|
|
|
#elif OS_ANDROID
|
2018-07-26 12:49:34 -07:00
|
|
|
return fml::MakeRefCounted<MessageLoopAndroid>();
|
2019-11-25 14:16:50 -08:00
|
|
|
#elif OS_FUCHSIA
|
|
|
|
|
return fml::MakeRefCounted<MessageLoopFuchsia>();
|
2018-04-13 13:48:15 -07:00
|
|
|
#elif OS_LINUX
|
2018-07-26 12:49:34 -07:00
|
|
|
return fml::MakeRefCounted<MessageLoopLinux>();
|
2018-04-13 13:48:15 -07:00
|
|
|
#elif OS_WIN
|
2018-07-26 12:49:34 -07:00
|
|
|
return fml::MakeRefCounted<MessageLoopWin>();
|
2018-04-13 13:48:15 -07:00
|
|
|
#else
|
|
|
|
|
return nullptr;
|
|
|
|
|
#endif
|
2017-03-20 13:41:41 -07:00
|
|
|
}
|
|
|
|
|
|
2019-06-19 14:03:14 -07:00
|
|
|
MessageLoopImpl::MessageLoopImpl()
|
|
|
|
|
: task_queue_(MessageLoopTaskQueues::GetInstance()),
|
|
|
|
|
queue_id_(task_queue_->CreateTaskQueue()),
|
|
|
|
|
terminated_(false) {
|
|
|
|
|
task_queue_->SetWakeable(queue_id_, this);
|
2019-06-13 10:14:13 -07:00
|
|
|
}
|
2017-03-20 13:41:41 -07:00
|
|
|
|
2019-08-22 23:27:25 -07:00
|
|
|
MessageLoopImpl::~MessageLoopImpl() {
|
|
|
|
|
task_queue_->Dispose(queue_id_);
|
|
|
|
|
}
|
2017-03-20 13:41:41 -07:00
|
|
|
|
2019-11-22 12:20:02 -08:00
|
|
|
void MessageLoopImpl::PostTask(const fml::closure& task,
|
|
|
|
|
fml::TimePoint target_time) {
|
2018-05-18 15:43:49 -07:00
|
|
|
FML_DCHECK(task != nullptr);
|
2019-06-13 10:14:13 -07:00
|
|
|
FML_DCHECK(task != nullptr);
|
|
|
|
|
if (terminated_) {
|
|
|
|
|
// If the message loop has already been terminated, PostTask should destruct
|
|
|
|
|
// |task| synchronously within this function.
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-06-19 14:03:14 -07:00
|
|
|
task_queue_->RegisterTask(queue_id_, task, target_time);
|
2017-03-20 13:41:41 -07:00
|
|
|
}
|
|
|
|
|
|
2019-11-22 12:20:02 -08:00
|
|
|
void MessageLoopImpl::AddTaskObserver(intptr_t key,
|
|
|
|
|
const fml::closure& callback) {
|
2018-05-18 15:43:49 -07:00
|
|
|
FML_DCHECK(callback != nullptr);
|
|
|
|
|
FML_DCHECK(MessageLoop::GetCurrent().GetLoopImpl().get() == this)
|
2017-03-23 15:29:33 -07:00
|
|
|
<< "Message loop task observer must be added on the same thread as the "
|
2017-03-20 13:41:41 -07:00
|
|
|
"loop.";
|
2019-08-20 17:28:59 -07:00
|
|
|
if (callback != nullptr) {
|
|
|
|
|
task_queue_->AddTaskObserver(queue_id_, key, callback);
|
|
|
|
|
} else {
|
|
|
|
|
FML_LOG(ERROR) << "Tried to add a null TaskObserver.";
|
|
|
|
|
}
|
2017-03-23 15:29:33 -07:00
|
|
|
}
|
|
|
|
|
|
2018-04-13 13:48:15 -07:00
|
|
|
void MessageLoopImpl::RemoveTaskObserver(intptr_t key) {
|
2018-05-18 15:43:49 -07:00
|
|
|
FML_DCHECK(MessageLoop::GetCurrent().GetLoopImpl().get() == this)
|
2017-03-23 15:29:33 -07:00
|
|
|
<< "Message loop task observer must be removed from the same thread as "
|
|
|
|
|
"the loop.";
|
2019-06-19 14:03:14 -07:00
|
|
|
task_queue_->RemoveTaskObserver(queue_id_, key);
|
2017-03-20 13:41:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MessageLoopImpl::DoRun() {
|
|
|
|
|
if (terminated_) {
|
|
|
|
|
// Message loops may be run only once.
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Allow the implementation to do its thing.
|
|
|
|
|
Run();
|
|
|
|
|
|
|
|
|
|
// The loop may have been implicitly terminated. This can happen if the
|
|
|
|
|
// implementation supports termination via platform specific APIs or just
|
|
|
|
|
// error conditions. Set the terminated flag manually.
|
|
|
|
|
terminated_ = true;
|
|
|
|
|
|
2017-03-31 13:39:23 -07:00
|
|
|
// The message loop is shutting down. Check if there are expired tasks. This
|
|
|
|
|
// is the last chance for expired tasks to be serviced. Make sure the
|
|
|
|
|
// terminated flag is already set so we don't accrue additional tasks now.
|
|
|
|
|
RunExpiredTasksNow();
|
|
|
|
|
|
2017-03-20 13:41:41 -07:00
|
|
|
// When the message loop is in the process of shutting down, pending tasks
|
|
|
|
|
// should be destructed on the message loop's thread. We have just returned
|
|
|
|
|
// from the implementations |Run| method which we know is on the correct
|
|
|
|
|
// thread. Drop all pending tasks on the floor.
|
2019-08-22 23:27:25 -07:00
|
|
|
task_queue_->DisposeTasks(queue_id_);
|
2017-03-20 13:41:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MessageLoopImpl::DoTerminate() {
|
|
|
|
|
terminated_ = true;
|
|
|
|
|
Terminate();
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-09 17:03:41 -07:00
|
|
|
void MessageLoopImpl::FlushTasks(FlushType type) {
|
2019-06-12 10:25:49 -07:00
|
|
|
TRACE_EVENT0("fml", "MessageLoop::FlushTasks");
|
2018-07-26 12:49:34 -07:00
|
|
|
std::vector<fml::closure> invocations;
|
2017-03-20 13:41:41 -07:00
|
|
|
|
2019-06-19 14:03:14 -07:00
|
|
|
task_queue_->GetTasksToRunNow(queue_id_, type, invocations);
|
2017-03-20 13:41:41 -07:00
|
|
|
|
|
|
|
|
for (const auto& invocation : invocations) {
|
|
|
|
|
invocation();
|
2019-08-22 23:27:25 -07:00
|
|
|
std::vector<fml::closure> observers =
|
|
|
|
|
task_queue_->GetObserversToNotify(queue_id_);
|
|
|
|
|
for (const auto& observer : observers) {
|
|
|
|
|
observer();
|
|
|
|
|
}
|
2017-03-20 13:41:41 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-09 17:03:41 -07:00
|
|
|
void MessageLoopImpl::RunExpiredTasksNow() {
|
|
|
|
|
FlushTasks(FlushType::kAll);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MessageLoopImpl::RunSingleExpiredTaskNow() {
|
|
|
|
|
FlushTasks(FlushType::kSingle);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-12 16:55:33 -07:00
|
|
|
TaskQueueId MessageLoopImpl::GetTaskQueueId() const {
|
|
|
|
|
return queue_id_;
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-20 13:41:41 -07:00
|
|
|
} // namespace fml
|