blob: 9ca2c555e532511fe3b0c7cbcb4244e0869c26fa [file] [log] [blame]
// Copyright 2024 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_IO_WATCHER_H_
#define BASE_MESSAGE_LOOP_IO_WATCHER_H_
#include <memory>
#include "base/base_export.h"
#include "base/location.h"
#include "base/message_loop/message_pump_for_io.h"
#include "base/types/pass_key.h"
#include "build/build_config.h"
#if defined(IS_WINDOWS)
#include "base/win/windows_types.h"
#endif
#if BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_IOS) && !BUILDFLAG(CRONET_BUILD))
#include <mach/mach.h>
#endif
namespace base {
// An object which can be used to register asynchronous IO handlers to wake the
// calling thread directly on interesting events. This is guaranteed to be
// usable on any MessagePumpType::IO thread, but it may also be usable on other
// thread types if the MessagePump implementation supports it.
class BASE_EXPORT IOWatcher {
public:
virtual ~IOWatcher() = default;
// Returns a valid IOWatcher instance iff it's usable from the calling thread.
// Returns null otherwise.
static IOWatcher* Get();
#if !BUILDFLAG(IS_NACL)
#if BUILDFLAG(IS_WIN)
// Please see MessagePumpWin for definitions of these methods.
[[nodiscard]] bool RegisterIOHandler(HANDLE file,
MessagePumpForIO::IOHandler* handler);
bool RegisterJobObject(HANDLE job, MessagePumpForIO::IOHandler* handler);
#elif BUILDFLAG(IS_POSIX)
class FdWatcher {
public:
virtual void OnFdReadable(int fd) = 0;
virtual void OnFdWritable(int fd) = 0;
protected:
virtual ~FdWatcher() = default;
};
// Effectively controls the lifetime of a single active FD watch started by
// WatchFileDescriptor() below.
class FdWatch {
public:
// FdWatch destruction immediately ceases watching the corresponding FD.
// Must be called on the same thread that made the original call to
// WatchFileDescriptor().
virtual ~FdWatch() = default;
};
// Asynchronously watches `fd` for IO. If successful, this returns a valid
// FdWatch object and the FD remains watched until the FdWatch object is
// destroyed OR a watched event occurs (for a non-persistent watch only);
// whichever occurs first. While the watch is active, `fd_watcher` will be
// invoked on the calling thread whenever an interesting IO event happens.
//
// The returned FdWatch MUST be destroyed on the calling thread, and
// `fd_watcher` MUST outlive it.
enum class FdWatchDuration {
kOneShot,
kPersistent,
};
enum class FdWatchMode {
kRead,
kWrite,
kReadWrite,
};
std::unique_ptr<FdWatch> WatchFileDescriptor(
int fd,
FdWatchDuration duration,
FdWatchMode mode,
FdWatcher& fd_watcher,
const Location& location = Location::Current());
#endif
#if BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_IOS) && !BUILDFLAG(CRONET_BUILD))
bool WatchMachReceivePort(
mach_port_t port,
MessagePumpForIO::MachPortWatchController* controller,
MessagePumpForIO::MachPortWatcher* delegate);
#elif BUILDFLAG(IS_FUCHSIA)
// Additional watch API for native platform resources.
bool WatchZxHandle(zx_handle_t handle,
bool persistent,
zx_signals_t signals,
MessagePumpForIO::ZxHandleWatchController* controller,
MessagePumpForIO::ZxHandleWatcher* delegate);
#endif // BUILDFLAG(IS_FUCHSIA)
#endif // !BUILDFLAG(IS_NACL)
protected:
IOWatcher();
// IOWatcher implementations must implement these methods for any applicable
// platform(s).
#if !BUILDFLAG(IS_NACL)
#if BUILDFLAG(IS_WIN)
virtual bool RegisterIOHandlerImpl(HANDLE file,
MessagePumpForIO::IOHandler* handler) = 0;
virtual bool RegisterJobObjectImpl(HANDLE job,
MessagePumpForIO::IOHandler* handler) = 0;
#elif BUILDFLAG(IS_POSIX)
virtual std::unique_ptr<FdWatch> WatchFileDescriptorImpl(
int fd,
FdWatchDuration duration,
FdWatchMode mode,
FdWatcher& fd_watcher,
const Location& location) = 0;
#endif
#if BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_IOS) && !BUILDFLAG(CRONET_BUILD))
virtual bool WatchMachReceivePortImpl(
mach_port_t port,
MessagePumpForIO::MachPortWatchController* controller,
MessagePumpForIO::MachPortWatcher* delegate) = 0;
#elif BUILDFLAG(IS_FUCHSIA)
virtual bool WatchZxHandleImpl(
zx_handle_t handle,
bool persistent,
zx_signals_t signals,
MessagePumpForIO::ZxHandleWatchController* controller,
MessagePumpForIO::ZxHandleWatcher* delegate) = 0;
#endif // BUILDFLAG(IS_FUCHSIA)
#endif // !BUILDFLAG(IS_NACL)
};
} // namespace base
#endif // BASE_MESSAGE_LOOP_IO_WATCHER_H_