24
24
using namespace lldb ;
25
25
using namespace lldb_private ;
26
26
27
- namespace {
28
-
29
- DWORD ToTimeout (std::optional<MainLoopWindows::TimePoint> point) {
27
+ static DWORD ToTimeout (std::optional<MainLoopWindows::TimePoint> point) {
30
28
using namespace std ::chrono;
31
29
32
30
if (!point)
@@ -36,40 +34,39 @@ DWORD ToTimeout(std::optional<MainLoopWindows::TimePoint> point) {
36
34
return ceil<milliseconds>(dur).count ();
37
35
}
38
36
39
- class PipeFdInfo : public MainLoopWindows ::FdInfo {
37
+ namespace {
38
+
39
+ class PipeEvent : public MainLoopWindows ::IOEvent {
40
40
public:
41
- explicit PipeFdInfo (HANDLE handle, MainLoopBase::Callback callback)
42
- : FdInfo((intptr_t )CreateEventW(NULL , /* bManualReset=*/ FALSE ,
43
- /* bInitialState=*/ FALSE , NULL ),
44
- callback),
45
- handle(handle), ready(CreateEventW(NULL , /* bManualReset=*/ FALSE ,
46
- /* bInitialState=*/ FALSE , NULL )) {
41
+ explicit PipeEvent (HANDLE handle)
42
+ : IOEvent((IOObject::WaitableHandle)CreateEventW(NULL , /* bManualReset=*/ FALSE ,
43
+ /* bInitialState=*/ FALSE , NULL )),
44
+ m_handle(handle), m_ready(CreateEventW(NULL , /* bManualReset=*/ FALSE ,
45
+ /* bInitialState=*/ FALSE , NULL )) {
47
46
assert (event && ready);
48
47
}
49
48
50
- ~PipeFdInfo () override {
51
- if (monitor_thread .joinable ()) {
52
- stopped = true ;
53
- SetEvent (ready );
49
+ ~PipeEvent () override {
50
+ if (m_monitor_thread .joinable ()) {
51
+ m_stopped = true ;
52
+ SetEvent (m_ready );
54
53
// Keep trying to cancel ReadFile() until the thread exits.
55
54
do {
56
- CancelIoEx ((HANDLE)handle , /* lpOverlapped=*/ NULL );
57
- } while (WaitForSingleObject (monitor_thread .native_handle (), 1 ) ==
55
+ CancelIoEx ((HANDLE)m_handle , /* lpOverlapped=*/ NULL );
56
+ } while (WaitForSingleObject (m_monitor_thread .native_handle (), 1 ) ==
58
57
WAIT_TIMEOUT);
59
- monitor_thread .join ();
58
+ m_monitor_thread .join ();
60
59
}
61
- CloseHandle ((HANDLE)event );
62
- CloseHandle (ready );
60
+ CloseHandle ((HANDLE)m_event );
61
+ CloseHandle (m_ready );
63
62
}
64
63
65
- void WillPoll () override {
66
- if (!monitor_thread .joinable ())
67
- monitor_thread = std::thread (&PipeFdInfo ::Monitor, this );
64
+ void WillPoll () override {
65
+ if (!m_monitor_thread .joinable ())
66
+ m_monitor_thread = std::thread (&PipeEvent ::Monitor, this );
68
67
}
69
68
70
- void Disarm () override {
71
- SetEvent (ready);
72
- }
69
+ void Disarm () override { SetEvent (m_ready); }
73
70
74
71
// / Monitors the handle performing a zero byte read to determine when data is
75
72
// / avaiable.
@@ -82,16 +79,17 @@ class PipeFdInfo : public MainLoopWindows::FdInfo {
82
79
// available in the pipe. The pipe must be PIPE_WAIT or this thread
83
80
// will spin.
84
81
BOOL success =
85
- ReadFile (handle , buf, /* nNumberOfBytesToRead=*/ 0 , &bytes_read, &ov);
82
+ ReadFile (m_handle , buf, /* nNumberOfBytesToRead=*/ 0 , &bytes_read, &ov);
86
83
DWORD bytes_available = 0 ;
87
84
DWORD err = GetLastError ();
88
85
if (!success && err == ERROR_IO_PENDING) {
89
- success = GetOverlappedResult (handle , &ov, &bytes_read,
86
+ success = GetOverlappedResult (m_handle , &ov, &bytes_read,
90
87
/* bWait=*/ TRUE );
91
88
err = GetLastError ();
92
89
}
93
90
if (success) {
94
- success = PeekNamedPipe (handle, NULL , 0 , NULL , &bytes_available, NULL );
91
+ success =
92
+ PeekNamedPipe (m_handle, NULL , 0 , NULL , &bytes_available, NULL );
95
93
err = GetLastError ();
96
94
}
97
95
if (success) {
@@ -108,51 +106,45 @@ class PipeFdInfo : public MainLoopWindows::FdInfo {
108
106
continue ;
109
107
}
110
108
111
- SetEvent ((HANDLE)event );
109
+ SetEvent ((HANDLE)m_event );
112
110
113
111
// Wait until the current read is consumed before doing the next read.
114
- WaitForSingleObject (ready , INFINITE);
115
- } while (!stopped );
112
+ WaitForSingleObject (m_ready , INFINITE);
113
+ } while (!m_stopped );
116
114
}
117
115
118
- HANDLE handle;
119
- HANDLE ready;
120
- std::thread monitor_thread;
121
- std::atomic<bool > stopped = false ;
116
+ private:
117
+ HANDLE m_handle;
118
+ HANDLE m_ready;
119
+ std::thread m_monitor_thread;
120
+ std::atomic<bool > m_stopped = false ;
122
121
};
123
122
124
- class SocketFdInfo : public MainLoopWindows ::FdInfo {
123
+ class SocketEvent : public MainLoopWindows ::IOEvent {
125
124
public:
126
- explicit SocketFdInfo (SOCKET socket, MainLoopBase::Callback callback )
127
- : FdInfo(( intptr_t )WSACreateEvent(), callback ), socket (socket) {
125
+ explicit SocketEvent (SOCKET socket)
126
+ : IOEvent((IOObject::WaitableHandle )WSACreateEvent()), m_socket (socket) {
128
127
assert (event != WSA_INVALID_EVENT);
129
128
}
130
129
131
- ~SocketFdInfo () override { WSACloseEvent ((HANDLE)event ); }
130
+ ~SocketEvent () override { WSACloseEvent ((HANDLE)m_event ); }
132
131
133
132
void WillPoll () {
134
- int result = WSAEventSelect (socket, (HANDLE)event, FD_READ | FD_ACCEPT | FD_CLOSE);
133
+ int result =
134
+ WSAEventSelect (m_socket, (HANDLE)m_event, FD_READ | FD_ACCEPT | FD_CLOSE);
135
135
assert (result == 0 );
136
136
UNUSED_IF_ASSERT_DISABLED (result);
137
137
}
138
138
139
139
void DidPoll () {
140
- int result = WSAEventSelect (socket , WSA_INVALID_EVENT, 0 );
140
+ int result = WSAEventSelect (m_socket , WSA_INVALID_EVENT, 0 );
141
141
assert (result == 0 );
142
142
UNUSED_IF_ASSERT_DISABLED (result);
143
143
}
144
144
145
- void Disarm () override {
146
- WSAResetEvent ((HANDLE)event);
147
- }
148
-
149
- SOCKET socket;
150
- };
145
+ void Disarm () override { WSAResetEvent ((HANDLE)m_event); }
151
146
152
- class FileFdInfo : public MainLoopWindows ::FdInfo {
153
- public:
154
- explicit FileFdInfo (HANDLE handle, MainLoopBase::Callback callback)
155
- : FdInfo((intptr_t )handle, callback) {}
147
+ SOCKET m_socket;
156
148
};
157
149
158
150
} // namespace
@@ -173,8 +165,8 @@ llvm::Expected<size_t> MainLoopWindows::Poll() {
173
165
std::vector<HANDLE> events;
174
166
events.reserve (m_read_fds.size () + 1 );
175
167
for (auto &[_, fd_info] : m_read_fds) {
176
- fd_info->WillPoll ();
177
- events.push_back ((HANDLE)fd_info-> event );
168
+ fd_info. event ->WillPoll ();
169
+ events.push_back ((HANDLE)fd_info. event -> GetHandle () );
178
170
}
179
171
events.push_back (m_interrupt_event);
180
172
@@ -183,7 +175,7 @@ llvm::Expected<size_t> MainLoopWindows::Poll() {
183
175
ToTimeout (GetNextWakeupTime ()), FALSE );
184
176
185
177
for (auto &[_, fd_info] : m_read_fds) {
186
- fd_info->DidPoll ();
178
+ fd_info. event ->DidPoll ();
187
179
}
188
180
189
181
if (result >= WSA_WAIT_EVENT_0 && result < WSA_WAIT_EVENT_0 + events.size ())
@@ -215,23 +207,16 @@ MainLoopWindows::RegisterReadObject(const IOObjectSP &object_sp,
215
207
}
216
208
217
209
if (object_sp->GetFdType () == IOObject::eFDTypeSocket)
218
- m_read_fds[waitable_handle] =
219
- std::make_unique<SocketFdInfo>((SOCKET)waitable_handle, callback);
220
- else
221
- switch (GetFileType (waitable_handle)) {
222
- case FILE_TYPE_PIPE:
223
- m_read_fds[waitable_handle] =
224
- std::make_unique<PipeFdInfo>((HANDLE)waitable_handle, callback);
225
- break ;
226
- case FILE_TYPE_DISK:
227
- m_read_fds[waitable_handle] =
228
- std::make_unique<FileFdInfo>((HANDLE)waitable_handle, callback);
229
- break ;
230
- default :
231
- error = Status::FromErrorStringWithFormat (" Unsupported file type %d" ,
232
- GetFileType (waitable_handle));
233
- return nullptr ;
234
- }
210
+ m_read_fds[waitable_handle] = {
211
+ std::make_unique<SocketEvent>((SOCKET)waitable_handle), callback};
212
+ else if (GetFileType (waitable_handle) == FILE_TYPE_PIPE)
213
+ m_read_fds[waitable_handle] = {
214
+ std::make_unique<PipeEvent>((HANDLE)waitable_handle), callback};
215
+ else {
216
+ error = Status::FromErrorStringWithFormat (" Unsupported file type %d" ,
217
+ GetFileType (waitable_handle));
218
+ return nullptr ;
219
+ }
235
220
236
221
return CreateReadHandle (object_sp);
237
222
}
@@ -254,8 +239,8 @@ Status MainLoopWindows::Run() {
254
239
255
240
if (*signaled_event < m_read_fds.size ()) {
256
241
auto &KV = *std::next (m_read_fds.begin (), *signaled_event);
257
- KV.second ->Disarm ();
258
- KV.second -> callback (*this ); // Do the work.
242
+ KV.second . event ->Disarm ();
243
+ KV.second . callback (*this ); // Do the work.
259
244
} else {
260
245
assert (*signaled_event == m_read_fds.size ());
261
246
WSAResetEvent (m_interrupt_event);
0 commit comments