mirror of
https://github.com/encounter/engine.git
synced 2026-03-30 11:09:55 -07:00
ca1d163d45
The number of workers depends on what the platform deem appropriate for the system at runtime.
94 lines
2.3 KiB
C++
94 lines
2.3 KiB
C++
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "flutter/fml/platform/linux/message_loop_linux.h"
|
|
|
|
#include <sys/epoll.h>
|
|
#include <unistd.h>
|
|
|
|
#include "flutter/fml/eintr_wrapper.h"
|
|
#include "flutter/fml/platform/linux/timerfd.h"
|
|
|
|
namespace fml {
|
|
|
|
static constexpr int kClockType = CLOCK_MONOTONIC;
|
|
|
|
MessageLoopLinux::MessageLoopLinux()
|
|
: epoll_fd_(FML_HANDLE_EINTR(::epoll_create(1 /* unused */))),
|
|
timer_fd_(::timerfd_create(kClockType, TFD_NONBLOCK | TFD_CLOEXEC)),
|
|
running_(false) {
|
|
FML_CHECK(epoll_fd_.is_valid());
|
|
FML_CHECK(timer_fd_.is_valid());
|
|
bool added_source = AddOrRemoveTimerSource(true);
|
|
FML_CHECK(added_source);
|
|
}
|
|
|
|
MessageLoopLinux::~MessageLoopLinux() {
|
|
bool removed_source = AddOrRemoveTimerSource(false);
|
|
FML_CHECK(removed_source);
|
|
}
|
|
|
|
bool MessageLoopLinux::AddOrRemoveTimerSource(bool add) {
|
|
struct epoll_event event = {};
|
|
|
|
event.events = EPOLLIN;
|
|
// The data is just for informational purposes so we know when we were worken
|
|
// by the FD.
|
|
event.data.fd = timer_fd_.get();
|
|
|
|
int ctl_result =
|
|
::epoll_ctl(epoll_fd_.get(), add ? EPOLL_CTL_ADD : EPOLL_CTL_DEL,
|
|
timer_fd_.get(), &event);
|
|
return ctl_result == 0;
|
|
}
|
|
|
|
// |fml::MessageLoopImpl|
|
|
void MessageLoopLinux::Run() {
|
|
running_ = true;
|
|
|
|
while (running_) {
|
|
struct epoll_event event = {};
|
|
|
|
int epoll_result = FML_HANDLE_EINTR(
|
|
::epoll_wait(epoll_fd_.get(), &event, 1, -1 /* timeout */));
|
|
|
|
// Errors are fatal.
|
|
if (event.events & (EPOLLERR | EPOLLHUP)) {
|
|
running_ = false;
|
|
continue;
|
|
}
|
|
|
|
// Timeouts are fatal since we specified an infinite timeout already.
|
|
// Likewise, > 1 is not possible since we waited for one result.
|
|
if (epoll_result != 1) {
|
|
running_ = false;
|
|
continue;
|
|
}
|
|
|
|
if (event.data.fd == timer_fd_.get()) {
|
|
OnEventFired();
|
|
}
|
|
}
|
|
}
|
|
|
|
// |fml::MessageLoopImpl|
|
|
void MessageLoopLinux::Terminate() {
|
|
running_ = false;
|
|
WakeUp(fml::TimePoint::Now());
|
|
}
|
|
|
|
// |fml::MessageLoopImpl|
|
|
void MessageLoopLinux::WakeUp(fml::TimePoint time_point) {
|
|
bool result = TimerRearm(timer_fd_.get(), time_point);
|
|
FML_DCHECK(result);
|
|
}
|
|
|
|
void MessageLoopLinux::OnEventFired() {
|
|
if (TimerDrain(timer_fd_.get())) {
|
|
RunExpiredTasksNow();
|
|
}
|
|
}
|
|
|
|
} // namespace fml
|