1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
base / message_loop / io_watcher.h [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_