1 // Copyright 2024 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_MESSAGE_LOOP_IO_WATCHER_H_ 6 #define BASE_MESSAGE_LOOP_IO_WATCHER_H_ 7 8 #include <memory> 9 10 #include "base/base_export.h" 11 #include "base/location.h" 12 #include "base/message_loop/message_pump_for_io.h" 13 #include "base/types/pass_key.h" 14 #include "build/build_config.h" 15 16 #if defined(IS_WINDOWS) 17 #include "base/win/windows_types.h" 18 #endif 19 20 #if BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_IOS) && !BUILDFLAG(CRONET_BUILD)) 21 #include <mach/mach.h> 22 #endif 23 24 namespace base { 25 26 // An object which can be used to register asynchronous IO handlers to wake the 27 // calling thread directly on interesting events. This is guaranteed to be 28 // usable on any MessagePumpType::IO thread, but it may also be usable on other 29 // thread types if the MessagePump implementation supports it. 30 class BASE_EXPORT IOWatcher { 31 public: 32 virtual ~IOWatcher() = default; 33 34 // Returns a valid IOWatcher instance iff it's usable from the calling thread. 35 // Returns null otherwise. 36 static IOWatcher* Get(); 37 38 #if !BUILDFLAG(IS_NACL) 39 #if BUILDFLAG(IS_WIN) 40 // Please see MessagePumpWin for definitions of these methods. 41 [[nodiscard]] bool RegisterIOHandler(HANDLE file, 42 MessagePumpForIO::IOHandler* handler); 43 bool RegisterJobObject(HANDLE job, MessagePumpForIO::IOHandler* handler); 44 #elif BUILDFLAG(IS_POSIX) 45 class FdWatcher { 46 public: 47 virtual void OnFdReadable(int fd) = 0; 48 virtual void OnFdWritable(int fd) = 0; 49 50 protected: 51 virtual ~FdWatcher() = default; 52 }; 53 54 // Effectively controls the lifetime of a single active FD watch started by 55 // WatchFileDescriptor() below. 56 class FdWatch { 57 public: 58 // FdWatch destruction immediately ceases watching the corresponding FD. 59 // Must be called on the same thread that made the original call to 60 // WatchFileDescriptor(). 61 virtual ~FdWatch() = default; 62 }; 63 64 // Asynchronously watches `fd` for IO. If successful, this returns a valid 65 // FdWatch object and the FD remains watched until the FdWatch object is 66 // destroyed OR a watched event occurs (for a non-persistent watch only); 67 // whichever occurs first. While the watch is active, `fd_watcher` will be 68 // invoked on the calling thread whenever an interesting IO event happens. 69 // 70 // The returned FdWatch MUST be destroyed on the calling thread, and 71 // `fd_watcher` MUST outlive it. 72 enum class FdWatchDuration { 73 kOneShot, 74 kPersistent, 75 }; 76 enum class FdWatchMode { 77 kRead, 78 kWrite, 79 kReadWrite, 80 }; 81 std::unique_ptr<FdWatch> WatchFileDescriptor( 82 int fd, 83 FdWatchDuration duration, 84 FdWatchMode mode, 85 FdWatcher& fd_watcher, 86 const Location& location = Location::Current()); 87 #endif 88 89 #if BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_IOS) && !BUILDFLAG(CRONET_BUILD)) 90 bool WatchMachReceivePort( 91 mach_port_t port, 92 MessagePumpForIO::MachPortWatchController* controller, 93 MessagePumpForIO::MachPortWatcher* delegate); 94 #elif BUILDFLAG(IS_FUCHSIA) 95 // Additional watch API for native platform resources. 96 bool WatchZxHandle(zx_handle_t handle, 97 bool persistent, 98 zx_signals_t signals, 99 MessagePumpForIO::ZxHandleWatchController* controller, 100 MessagePumpForIO::ZxHandleWatcher* delegate); 101 #endif // BUILDFLAG(IS_FUCHSIA) 102 #endif // !BUILDFLAG(IS_NACL) 103 104 protected: 105 IOWatcher(); 106 107 // IOWatcher implementations must implement these methods for any applicable 108 // platform(s). 109 #if !BUILDFLAG(IS_NACL) 110 #if BUILDFLAG(IS_WIN) 111 virtual bool RegisterIOHandlerImpl(HANDLE file, 112 MessagePumpForIO::IOHandler* handler) = 0; 113 virtual bool RegisterJobObjectImpl(HANDLE job, 114 MessagePumpForIO::IOHandler* handler) = 0; 115 #elif BUILDFLAG(IS_POSIX) 116 virtual std::unique_ptr<FdWatch> WatchFileDescriptorImpl( 117 int fd, 118 FdWatchDuration duration, 119 FdWatchMode mode, 120 FdWatcher& fd_watcher, 121 const Location& location) = 0; 122 #endif 123 #if BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_IOS) && !BUILDFLAG(CRONET_BUILD)) 124 virtual bool WatchMachReceivePortImpl( 125 mach_port_t port, 126 MessagePumpForIO::MachPortWatchController* controller, 127 MessagePumpForIO::MachPortWatcher* delegate) = 0; 128 #elif BUILDFLAG(IS_FUCHSIA) 129 virtual bool WatchZxHandleImpl( 130 zx_handle_t handle, 131 bool persistent, 132 zx_signals_t signals, 133 MessagePumpForIO::ZxHandleWatchController* controller, 134 MessagePumpForIO::ZxHandleWatcher* delegate) = 0; 135 #endif // BUILDFLAG(IS_FUCHSIA) 136 #endif // !BUILDFLAG(IS_NACL) 137 }; 138 139 } // namespace base 140 141 #endif // BASE_MESSAGE_LOOP_IO_WATCHER_H_ 142