chromium/base/message_loop/message_pump_epoll.h

// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_EPOLL_H_
#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_EPOLL_H_

#include <poll.h>
#include <sys/epoll.h>

#include <cstdint>
#include <map>

#include "base/base_export.h"
#include "base/feature_list.h"
#include "base/files/scoped_file.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ptr_exclusion.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_pump.h"
#include "base/message_loop/watchable_io_message_pump_posix.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "third_party/abseil-cpp/absl/container/inlined_vector.h"

namespace base {

// Use poll() rather than epoll().
//
// Why? epoll() is supposed to be strictly better. But it has one consequence
// we don't necessarily want: when writing to a AF_UNIX socket, the kernel
// will wake up the waiter with a "sync" wakeup. The concept of a "sync"
// wakeup has various consequences, but on Android it tends to bias the
// scheduler towards a "baton passing" mode, where the current thread yields
// its CPU to the target. This is desirable to lower latency.
//
// However, when using epoll_wait(), the "sync" flag is dropped from the
// wakeup path. This is not the case with poll(). So let's use it to preserve
// this behavior.
//
// Caveat: Since both we and the kernel need to walk the list of all fds at
// every call, don't do it when we have too many FDs.
BASE_FEATURE();

// A MessagePump implementation suitable for I/O message loops on Linux-based
// systems with epoll API support.
class BASE_EXPORT MessagePumpEpoll : public MessagePump,
                                     public WatchableIOMessagePumpPosix {};

}  // namespace base

#endif  // BASE_MESSAGE_LOOP_MESSAGE_PUMP_EPOLL_H_