Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
message_loop_linux.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#include "flutter/fml/platform/linux/message_loop_linux.h"
6
7#include <sys/epoll.h>
8#include <unistd.h>
9
10#include "flutter/fml/eintr_wrapper.h"
11#include "flutter/fml/platform/linux/timerfd.h"
12
13namespace fml {
14
15static constexpr int kClockType = CLOCK_MONOTONIC;
16
17MessageLoopLinux::MessageLoopLinux()
18 : epoll_fd_(FML_HANDLE_EINTR(::epoll_create(1 /* unused */))),
20 FML_CHECK(epoll_fd_.is_valid());
21 FML_CHECK(timer_fd_.is_valid());
22 bool added_source = AddOrRemoveTimerSource(true);
23 FML_CHECK(added_source);
24}
25
26MessageLoopLinux::~MessageLoopLinux() {
27 bool removed_source = AddOrRemoveTimerSource(false);
28 FML_CHECK(removed_source);
29}
30
31bool MessageLoopLinux::AddOrRemoveTimerSource(bool add) {
32 struct epoll_event event = {};
33
34 event.events = EPOLLIN;
35 // The data is just for informational purposes so we know when we were worken
36 // by the FD.
37 event.data.fd = timer_fd_.get();
38
39 int ctl_result =
40 ::epoll_ctl(epoll_fd_.get(), add ? EPOLL_CTL_ADD : EPOLL_CTL_DEL,
41 timer_fd_.get(), &event);
42 return ctl_result == 0;
43}
44
45// |fml::MessageLoopImpl|
46void MessageLoopLinux::Run() {
47 running_ = true;
48
49 while (running_) {
50 struct epoll_event event = {};
51
52 int epoll_result = FML_HANDLE_EINTR(
53 ::epoll_wait(epoll_fd_.get(), &event, 1, -1 /* timeout */));
54
55 // Errors are fatal.
56 if (event.events & (EPOLLERR | EPOLLHUP)) {
57 running_ = false;
58 continue;
59 }
60
61 // Timeouts are fatal since we specified an infinite timeout already.
62 // Likewise, > 1 is not possible since we waited for one result.
63 if (epoll_result != 1) {
64 running_ = false;
65 continue;
66 }
67
68 if (event.data.fd == timer_fd_.get()) {
69 OnEventFired();
70 }
71 }
72}
73
74// |fml::MessageLoopImpl|
75void MessageLoopLinux::Terminate() {
76 running_ = false;
77 WakeUp(fml::TimePoint::Now());
78}
79
80// |fml::MessageLoopImpl|
81void MessageLoopLinux::WakeUp(fml::TimePoint time_point) {
82 bool result = TimerRearm(timer_fd_.get(), time_point);
83 (void)result;
85}
86
87void MessageLoopLinux::OnEventFired() {
88 if (TimerDrain(timer_fd_.get())) {
89 RunExpiredTasksNow();
90 }
91}
92
93} // namespace fml
static TimePoint Now()
Definition time_point.cc:49
FlKeyEvent * event
GAsyncResult * result
#define FML_HANDLE_EINTR(x)
#define FML_CHECK(condition)
Definition logging.h:85
#define FML_DCHECK(condition)
Definition logging.h:103
static constexpr int kClockType
bool TimerRearm(int fd, fml::TimePoint time_point)
Rearms the timer to expire at the given time point.
Definition timerfd.cc:38
bool TimerDrain(int fd)
Definition timerfd.cc:59
int timerfd_create(int clockid, int flags)
Definition timerfd.cc:19
#define TFD_NONBLOCK
Definition timerfd.h:33
#define TFD_CLOEXEC
Definition timerfd.h:32