diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 9b06eb3f8b..d95b1e7d50 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include @@ -992,23 +992,54 @@ void DNS_Mgr::Resolve() { int nfds = 0; struct timeval *tvp, tv; - fd_set read_fds, write_fds; + struct pollfd pollfds[ARES_GETSOCK_MAXNUM]; + ares_socket_t socks[ARES_GETSOCK_MAXNUM]; tv.tv_sec = DNS_TIMEOUT; tv.tv_usec = 0; for ( int i = 0; i < MAX_PENDING_REQUESTS; i++ ) { - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - nfds = ares_fds(channel, &read_fds, &write_fds); + int nfds = 0; + int bitmap = ares_getsock(channel, socks, ARES_GETSOCK_MAXNUM); + + for ( int i = 0; i < ARES_GETSOCK_MAXNUM; i++ ) + { + bool rd = ARES_GETSOCK_READABLE(bitmap, i); + bool wr = ARES_GETSOCK_WRITABLE(bitmap, i); + if ( rd || wr ) + { + pollfds[nfds].fd = socks[i]; + pollfds[nfds].events = rd ? POLLIN : 0; + pollfds[nfds].events |= wr ? POLLOUT : 0; + ++nfds; + } + } + + // Do we have any sockets that are read or writable? if ( nfds == 0 ) break; + // poll() timeout is in milliseconds. tvp = ares_timeout(channel, &tv, &tv); - int res = select(nfds, &read_fds, &write_fds, NULL, tvp); - if ( res >= 0 ) - ares_process(channel, &read_fds, &write_fds); + int timeout_ms = tvp->tv_sec * 1000 + tvp->tv_usec / 1000; + + int res = poll(pollfds, nfds, timeout_ms); + + if ( res > 0 ) + { + for ( int i = 0; i < nfds; i++ ) + { + int rdfd = pollfds[i].revents | POLLIN ? pollfds[i].fd : ARES_SOCKET_BAD; + int wrfd = pollfds[i].revents | POLLOUT ? pollfds[i].fd : ARES_SOCKET_BAD; + + if ( rdfd != ARES_SOCKET_BAD || wrfd != ARES_SOCKET_BAD ) + ares_process_fd(channel, rdfd, wrfd); + } + } + else if ( res == 0 ) + // Do timeout processing when poll() timed out. + ares_process_fd(channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD); } } @@ -1442,11 +1473,16 @@ double DNS_Mgr::GetNextTimeout() if ( asyncs_pending == 0 ) return -1; - fd_set read_fds, write_fds; + int nfds = 0; + ares_socket_t socks[ARES_GETSOCK_MAXNUM]; + int bitmap = ares_getsock(channel, socks, ARES_GETSOCK_MAXNUM); + for ( int i = 0; i < ARES_GETSOCK_MAXNUM; i++ ) + { + if ( ARES_GETSOCK_READABLE(bitmap, i) || ARES_GETSOCK_WRITABLE(bitmap, i) ) + ++nfds; + } - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - int nfds = ares_fds(channel, &read_fds, &write_fds); + // Do we have any sockets that are read or writable? if ( nfds == 0 ) return -1;