Skip to content

Commit 4ff8fbf

Browse files
committed
Fix benchmark test problem on Windows
1 parent 318a3fe commit 4ff8fbf

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

httplib.h

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3246,8 +3246,11 @@ inline int poll_wrapper(struct pollfd *fds, nfds_t nfds, int timeout) {
32463246

32473247
template <bool Read>
32483248
inline ssize_t select_impl(socket_t sock, time_t sec, time_t usec) {
3249+
#if defined(__APPLE__) || defined(_WIN32)
3250+
// Use select() on macOS and Windows for better performance
32493251
#ifdef __APPLE__
32503252
if (sock >= FD_SETSIZE) { return -1; }
3253+
#endif
32513254

32523255
fd_set fds, *rfds, *wfds;
32533256
FD_ZERO(&fds);
@@ -3260,9 +3263,15 @@ inline ssize_t select_impl(socket_t sock, time_t sec, time_t usec) {
32603263
tv.tv_usec = static_cast<decltype(tv.tv_usec)>(usec);
32613264

32623265
return handle_EINTR([&]() {
3266+
#ifdef _WIN32
3267+
// On Windows, the first parameter of select() is ignored
3268+
return select(0, rfds, wfds, nullptr, &tv);
3269+
#else
32633270
return select(static_cast<int>(sock + 1), rfds, wfds, nullptr, &tv);
3271+
#endif
32643272
});
32653273
#else
3274+
// Use poll() on Linux and other POSIX systems
32663275
struct pollfd pfd;
32673276
pfd.fd = sock;
32683277
pfd.events = (Read ? POLLIN : POLLOUT);
@@ -3283,25 +3292,43 @@ inline ssize_t select_write(socket_t sock, time_t sec, time_t usec) {
32833292

32843293
inline Error wait_until_socket_is_ready(socket_t sock, time_t sec,
32853294
time_t usec) {
3295+
#if defined(__APPLE__) || defined(_WIN32)
3296+
// Use select() on macOS and Windows.
3297+
// WSAPoll() on Windows has known performance issues with localhost
3298+
// connections. See: https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/
32863299
#ifdef __APPLE__
3300+
// On macOS, check if socket descriptor exceeds FD_SETSIZE
32873301
if (sock >= FD_SETSIZE) { return Error::Connection; }
3302+
#endif
32883303

3289-
fd_set fdsr, fdsw;
3304+
fd_set fdsr, fdsw, fdse;
32903305
FD_ZERO(&fdsr);
32913306
FD_ZERO(&fdsw);
3307+
FD_ZERO(&fdse);
32923308
FD_SET(sock, &fdsr);
32933309
FD_SET(sock, &fdsw);
3310+
FD_SET(sock, &fdse);
32943311

32953312
timeval tv;
32963313
tv.tv_sec = static_cast<long>(sec);
32973314
tv.tv_usec = static_cast<decltype(tv.tv_usec)>(usec);
32983315

32993316
auto ret = handle_EINTR([&]() {
3300-
return select(static_cast<int>(sock + 1), &fdsr, &fdsw, nullptr, &tv);
3317+
#ifdef _WIN32
3318+
// On Windows, the first parameter of select() is ignored
3319+
return select(0, &fdsr, &fdsw, &fdse, &tv);
3320+
#else
3321+
return select(static_cast<int>(sock + 1), &fdsr, &fdsw, &fdse, &tv);
3322+
#endif
33013323
});
33023324

33033325
if (ret == 0) { return Error::ConnectionTimeout; }
33043326

3327+
if (ret > 0 && (FD_ISSET(sock, &fdse))) {
3328+
// Socket has an exception (connection failed)
3329+
return Error::Connection;
3330+
}
3331+
33053332
if (ret > 0 && (FD_ISSET(sock, &fdsr) || FD_ISSET(sock, &fdsw))) {
33063333
auto error = 0;
33073334
socklen_t len = sizeof(error);
@@ -3313,6 +3340,7 @@ inline Error wait_until_socket_is_ready(socket_t sock, time_t sec,
33133340

33143341
return Error::Connection;
33153342
#else
3343+
// Use poll() on Linux and other POSIX systems
33163344
struct pollfd pfd_read;
33173345
pfd_read.fd = sock;
33183346
pfd_read.events = POLLIN | POLLOUT;

0 commit comments

Comments
 (0)