// 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 #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 #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 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 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_