in demo_example/asio/asio/detail/impl/socket_ops.ipp [2161:2200]
int select(int nfds, fd_set* readfds, fd_set* writefds,
fd_set* exceptfds, timeval* timeout, asio::error_code& ec)
{
#if defined(__EMSCRIPTEN__)
exceptfds = 0;
#endif // defined(__EMSCRIPTEN__)
#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
if (!readfds && !writefds && !exceptfds && timeout)
{
DWORD milliseconds = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
if (milliseconds == 0)
milliseconds = 1; // Force context switch.
::Sleep(milliseconds);
ec.assign(0, ec.category());
return 0;
}
// The select() call allows timeout values measured in microseconds, but the
// system clock (as wrapped by boost::posix_time::microsec_clock) typically
// has a resolution of 10 milliseconds. This can lead to a spinning select
// reactor, meaning increased CPU usage, when waiting for the earliest
// scheduled timeout if it's less than 10 milliseconds away. To avoid a tight
// spin we'll use a minimum timeout of 1 millisecond.
if (timeout && timeout->tv_sec == 0
&& timeout->tv_usec > 0 && timeout->tv_usec < 1000)
timeout->tv_usec = 1000;
#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)
#if defined(__hpux) && defined(__SELECT)
timespec ts;
ts.tv_sec = timeout ? timeout->tv_sec : 0;
ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0;
int result = ::pselect(nfds, readfds,
writefds, exceptfds, timeout ? &ts : 0, 0);
#else
int result = ::select(nfds, readfds, writefds, exceptfds, timeout);
#endif
get_last_error(ec, result < 0);
return result;
}