• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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