Skip to content

Commit 8546986

Browse files
committed
Use poll() instead of select() to manage timeout
1 parent 16d3f23 commit 8546986

File tree

2 files changed

+21
-21
lines changed

2 files changed

+21
-21
lines changed

llvm/include/llvm/Support/raw_socket_stream.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@ class ListeningSocket {
8181
/// specified amount of time has passed. By default the method will block
8282
/// until the socket has recieved a connection
8383
///
84-
/// \param Timeout An optional timeout duration in microseconds
84+
/// \param Timeout An optional timeout duration in milliseconds
8585
///
8686
Expected<std::unique_ptr<raw_socket_stream>>
87-
accept(std::optional<std::chrono::microseconds> Timeout = std::nullopt);
87+
accept(std::optional<std::chrono::milliseconds> Timeout = std::nullopt);
8888

8989
/// Creates a listening socket bound to the specified file system path.
9090
/// Handles the socket creation, binding, and immediately starts listening for

llvm/lib/Support/raw_socket_stream.cpp

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/Support/FileSystem.h"
1818

1919
#include <atomic>
20+
#include <poll.h>
2021

2122
#ifndef _WIN32
2223
#include <sys/socket.h>
@@ -165,45 +166,44 @@ ListeningSocket::createListeningUnixSocket(StringRef SocketPath,
165166
}
166167

167168
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) {
169170

170-
fd_set Readfds;
171-
FD_ZERO(&Readfds);
171+
struct pollfd FDs[1];
172+
FDs[0].events = POLLIN;
172173
#ifdef _WIN32
173174
SOCKET WinServerSock = _get_osfhandle(FD);
174-
FD_SET(WinServerSock, &Readfds);
175+
FDs[0].fd = WinServerSock;
175176
#else
176-
FD_SET(FD, &Readfds);
177+
FDs[0].fd = FD;
177178
#endif
178179

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);
186182

187-
if (SelectStatus == -1)
183+
if (PollStatus == -1)
188184
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");
190195

191196
int AcceptFD;
192-
if (SelectStatus) {
193197
#ifdef _WIN32
194198
SOCKET WinAcceptSock = ::accept(WinServerSock, NULL, NULL);
195199
AcceptFD = _open_osfhandle(WinAcceptSock, 0);
196200
#else
197201
AcceptFD = ::accept(FD, NULL, NULL);
198202
#endif
199-
} else
200-
return llvm::make_error<StringError>(
201-
std::make_error_code(std::errc::timed_out), "accept timed out");
202203

203204
if (AcceptFD == -1)
204205
return llvm::make_error<StringError>(getLastSocketErrorCode(),
205206
"accept failed");
206-
207207
return std::make_unique<raw_socket_stream>(AcceptFD);
208208
}
209209

0 commit comments

Comments
 (0)