int select()

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;
}