|
17 | 17 | #include "llvm/Support/FileSystem.h"
|
18 | 18 |
|
19 | 19 | #include <atomic>
|
| 20 | +#include <poll.h> |
20 | 21 |
|
21 | 22 | #ifndef _WIN32
|
22 | 23 | #include <sys/socket.h>
|
@@ -165,45 +166,44 @@ ListeningSocket::createListeningUnixSocket(StringRef SocketPath,
|
165 | 166 | }
|
166 | 167 |
|
167 | 168 | Expected<std::unique_ptr<raw_socket_stream>>
|
168 |
| -ListeningSocket::accept(std::optional<std::chrono::microseconds> Timeout) { |
| 169 | +ListeningSocket::accept(std::optional<std::chrono::milliseconds> Timeout) { |
169 | 170 |
|
170 |
| - fd_set Readfds; |
171 |
| - FD_ZERO(&Readfds); |
| 171 | + struct pollfd FDs[1]; |
| 172 | + FDs[0].events = POLLIN; |
172 | 173 | #ifdef _WIN32
|
173 | 174 | SOCKET WinServerSock = _get_osfhandle(FD);
|
174 |
| - FD_SET(WinServerSock, &Readfds); |
| 175 | + FDs[0].fd = WinServerSock; |
175 | 176 | #else
|
176 |
| - FD_SET(FD, &Readfds); |
| 177 | + FDs[0].fd = FD; |
177 | 178 | #endif
|
178 | 179 |
|
179 |
| - int SelectStatus; |
180 |
| - if (Timeout.has_value()) { |
181 |
| - timeval TV = {0, Timeout.value().count()}; |
182 |
| - SelectStatus = ::select(FD + 1, &Readfds, NULL, NULL, &TV); |
183 |
| - } else { |
184 |
| - SelectStatus = ::select(FD + 1, &Readfds, NULL, NULL, NULL); |
185 |
| - } |
| 180 | + int TimeoutCount = Timeout.value_or(std::chrono::milliseconds(-1)).count(); |
| 181 | + int PollStatus = ::poll(FDs, 1, TimeoutCount); |
186 | 182 |
|
187 |
| - if (SelectStatus == -1) |
| 183 | + if (PollStatus == -1) |
188 | 184 | return llvm::make_error<StringError>(getLastSocketErrorCode(),
|
189 |
| - "select failed"); |
| 185 | + "poll failed"); |
| 186 | + if (PollStatus == 0) |
| 187 | + return llvm::make_error<StringError>( |
| 188 | + std::make_error_code(std::errc::timed_out), |
| 189 | + "No client requests within timeout window"); |
| 190 | + |
| 191 | + if (FDs[0].revents & POLLNVAL) |
| 192 | + return llvm::make_error<StringError>( |
| 193 | + std::make_error_code(std::errc::bad_file_descriptor), |
| 194 | + "File descriptor closed by another thread"); |
190 | 195 |
|
191 | 196 | int AcceptFD;
|
192 |
| - if (SelectStatus) { |
193 | 197 | #ifdef _WIN32
|
194 | 198 | SOCKET WinAcceptSock = ::accept(WinServerSock, NULL, NULL);
|
195 | 199 | AcceptFD = _open_osfhandle(WinAcceptSock, 0);
|
196 | 200 | #else
|
197 | 201 | AcceptFD = ::accept(FD, NULL, NULL);
|
198 | 202 | #endif
|
199 |
| - } else |
200 |
| - return llvm::make_error<StringError>( |
201 |
| - std::make_error_code(std::errc::timed_out), "accept timed out"); |
202 | 203 |
|
203 | 204 | if (AcceptFD == -1)
|
204 | 205 | return llvm::make_error<StringError>(getLastSocketErrorCode(),
|
205 | 206 | "accept failed");
|
206 |
| - |
207 | 207 | return std::make_unique<raw_socket_stream>(AcceptFD);
|
208 | 208 | }
|
209 | 209 |
|
|
0 commit comments