mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
Fix WSAPoll (#1265)
* Fix calling WSAPoll. * fast_reload: explicitly set tcp_wouldblock on Windows when there is no command to read from the fast_reload thread. * For poll(), also check for ENOMEM (Linux). * Remove ifdefs for ENOMEM. * Some systems return EAGAIN for poll.
This commit is contained in:
parent
4f06e658d1
commit
75e8fd7539
2 changed files with 64 additions and 41 deletions
|
|
@ -3899,6 +3899,7 @@ sock_poll_timeout(int fd, int timeout, int pollin, int pollout, int* event)
|
|||
{
|
||||
int loopcount = 0;
|
||||
/* Loop if the system call returns an errno to do so, like EINTR. */
|
||||
log_assert(pollin || pollout);
|
||||
while(1) {
|
||||
struct pollfd p, *fds;
|
||||
int nfds, ret;
|
||||
|
|
@ -3916,11 +3917,11 @@ sock_poll_timeout(int fd, int timeout, int pollin, int pollout, int* event)
|
|||
nfds = 1;
|
||||
memset(&p, 0, sizeof(p));
|
||||
p.fd = fd;
|
||||
p.events = POLLERR
|
||||
#ifndef USE_WINSOCK
|
||||
p.events = POLLERR
|
||||
| POLLHUP
|
||||
#endif
|
||||
;
|
||||
#endif
|
||||
if(pollin)
|
||||
p.events |= POLLIN;
|
||||
if(pollout)
|
||||
|
|
@ -3937,19 +3938,20 @@ sock_poll_timeout(int fd, int timeout, int pollin, int pollout, int* event)
|
|||
}
|
||||
#endif
|
||||
if(ret == -1) {
|
||||
if(
|
||||
#ifndef USE_WINSOCK
|
||||
if(
|
||||
errno == EINTR || errno == EAGAIN
|
||||
# ifdef EWOULDBLOCK
|
||||
|| errno == EWOULDBLOCK
|
||||
# endif
|
||||
#else
|
||||
WSAGetLastError() == WSAEINTR ||
|
||||
WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAEWOULDBLOCK
|
||||
) continue; /* Try again. */
|
||||
#endif
|
||||
)
|
||||
continue; /* Try again. */
|
||||
/* For WSAPoll we only get errors here:
|
||||
* o WSAENETDOWN
|
||||
* o WSAEFAULT
|
||||
* o WSAEINVAL
|
||||
* o WSAENOBUFS
|
||||
*/
|
||||
log_err("poll: %s", sock_strerror(errno));
|
||||
if(event)
|
||||
*event = 0;
|
||||
|
|
@ -7392,11 +7394,17 @@ fr_main_handle_cmd(struct fast_reload_thread* fr)
|
|||
# endif
|
||||
#else
|
||||
WSAGetLastError() == WSAEINTR ||
|
||||
WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAEWOULDBLOCK
|
||||
WSAGetLastError() == WSAEINPROGRESS
|
||||
#endif
|
||||
)
|
||||
return; /* Continue later. */
|
||||
#ifdef USE_WINSOCK
|
||||
if(WSAGetLastError() == WSAEWOULDBLOCK) {
|
||||
ub_winsock_tcp_wouldblock(fr->service_event,
|
||||
UB_EV_READ);
|
||||
return; /* Continue later. */
|
||||
}
|
||||
#endif
|
||||
log_err("read cmd from fast reload thread, recv: %s",
|
||||
sock_strerror(errno));
|
||||
return;
|
||||
|
|
@ -7428,10 +7436,23 @@ fr_check_cmd_from_thread(struct fast_reload_thread* fr)
|
|||
if(!sock_poll_timeout(fr->commpair[0], 0, 1, 0, &inevent)) {
|
||||
log_err("check for cmd from fast reload thread: "
|
||||
"poll failed");
|
||||
#ifdef USE_WINSOCK
|
||||
if(worker->daemon->fast_reload_thread)
|
||||
ub_winsock_tcp_wouldblock(worker->daemon->
|
||||
fast_reload_thread->service_event,
|
||||
UB_EV_READ);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if(!inevent)
|
||||
if(!inevent) {
|
||||
#ifdef USE_WINSOCK
|
||||
if(worker->daemon->fast_reload_thread)
|
||||
ub_winsock_tcp_wouldblock(worker->daemon->
|
||||
fast_reload_thread->service_event,
|
||||
UB_EV_READ);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
fr_main_handle_cmd(fr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -456,9 +456,9 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
|
|||
int pret;
|
||||
memset(&p, 0, sizeof(p));
|
||||
p.fd = c->fd;
|
||||
p.events = POLLOUT | POLLERR
|
||||
p.events = POLLOUT
|
||||
#ifndef USE_WINSOCK
|
||||
| POLLHUP
|
||||
| POLLERR | POLLHUP
|
||||
#endif
|
||||
;
|
||||
# ifndef USE_WINSOCK
|
||||
|
|
@ -483,7 +483,7 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
|
|||
# ifdef EWOULDBLOCK
|
||||
errno != EWOULDBLOCK &&
|
||||
# endif
|
||||
errno != ENOBUFS
|
||||
errno != ENOMEM && errno != ENOBUFS
|
||||
#else
|
||||
WSAGetLastError() != WSAEINPROGRESS &&
|
||||
WSAGetLastError() != WSAEINTR &&
|
||||
|
|
@ -496,15 +496,19 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
|
|||
return 0;
|
||||
} else if((pret < 0 &&
|
||||
#ifndef USE_WINSOCK
|
||||
errno == ENOBUFS
|
||||
( errno == ENOBUFS /* Maybe some systems */
|
||||
|| errno == ENOMEM /* Linux */
|
||||
|| errno == EAGAIN) /* Macos, solaris, openbsd */
|
||||
#else
|
||||
WSAGetLastError() == WSAENOBUFS
|
||||
#endif
|
||||
) || (send_nobufs && retries > 0)) {
|
||||
/* ENOBUFS, and poll returned without
|
||||
/* ENOBUFS/ENOMEM/EAGAIN, and poll
|
||||
* returned without
|
||||
* a timeout. Or the retried send call
|
||||
* returned ENOBUFS. It is good to
|
||||
* wait a bit for the error to clear. */
|
||||
* returned ENOBUFS/ENOMEM/EAGAIN.
|
||||
* It is good to wait a bit for the
|
||||
* error to clear. */
|
||||
/* The timeout is 20*(2^(retries+1)),
|
||||
* it increases exponentially, starting
|
||||
* at 40 msec. After 5 tries, 1240 msec
|
||||
|
|
@ -517,18 +521,15 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
|
|||
Sleep((SEND_BLOCKED_WAIT_TIMEOUT/10)<<(retries+1));
|
||||
pret = 0;
|
||||
#endif
|
||||
if(pret < 0 &&
|
||||
if(pret < 0
|
||||
#ifndef USE_WINSOCK
|
||||
errno != EAGAIN && errno != EINTR &&
|
||||
&& errno != EAGAIN && errno != EINTR &&
|
||||
# ifdef EWOULDBLOCK
|
||||
errno != EWOULDBLOCK &&
|
||||
# endif
|
||||
errno != ENOBUFS
|
||||
errno != ENOMEM && errno != ENOBUFS
|
||||
#else
|
||||
WSAGetLastError() != WSAEINPROGRESS &&
|
||||
WSAGetLastError() != WSAEINTR &&
|
||||
WSAGetLastError() != WSAENOBUFS &&
|
||||
WSAGetLastError() != WSAEWOULDBLOCK
|
||||
/* Sleep does not error */
|
||||
#endif
|
||||
) {
|
||||
log_err("poll udp out timer failed: %s",
|
||||
|
|
@ -770,9 +771,9 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet,
|
|||
int pret;
|
||||
memset(&p, 0, sizeof(p));
|
||||
p.fd = c->fd;
|
||||
p.events = POLLOUT | POLLERR
|
||||
p.events = POLLOUT
|
||||
#ifndef USE_WINSOCK
|
||||
| POLLHUP
|
||||
| POLLERR | POLLHUP
|
||||
#endif
|
||||
;
|
||||
# ifndef USE_WINSOCK
|
||||
|
|
@ -797,7 +798,7 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet,
|
|||
# ifdef EWOULDBLOCK
|
||||
errno != EWOULDBLOCK &&
|
||||
# endif
|
||||
errno != ENOBUFS
|
||||
errno != ENOMEM && errno != ENOBUFS
|
||||
#else
|
||||
WSAGetLastError() != WSAEINPROGRESS &&
|
||||
WSAGetLastError() != WSAEINTR &&
|
||||
|
|
@ -810,15 +811,19 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet,
|
|||
return 0;
|
||||
} else if((pret < 0 &&
|
||||
#ifndef USE_WINSOCK
|
||||
errno == ENOBUFS
|
||||
( errno == ENOBUFS /* Maybe some systems */
|
||||
|| errno == ENOMEM /* Linux */
|
||||
|| errno == EAGAIN) /* Macos, solaris, openbsd */
|
||||
#else
|
||||
WSAGetLastError() == WSAENOBUFS
|
||||
#endif
|
||||
) || (send_nobufs && retries > 0)) {
|
||||
/* ENOBUFS, and poll returned without
|
||||
/* ENOBUFS/ENOMEM/EAGAIN, and poll
|
||||
* returned without
|
||||
* a timeout. Or the retried send call
|
||||
* returned ENOBUFS. It is good to
|
||||
* wait a bit for the error to clear. */
|
||||
* returned ENOBUFS/ENOMEM/EAGAIN.
|
||||
* It is good to wait a bit for the
|
||||
* error to clear. */
|
||||
/* The timeout is 20*(2^(retries+1)),
|
||||
* it increases exponentially, starting
|
||||
* at 40 msec. After 5 tries, 1240 msec
|
||||
|
|
@ -831,18 +836,15 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet,
|
|||
Sleep((SEND_BLOCKED_WAIT_TIMEOUT/10)<<(retries+1));
|
||||
pret = 0;
|
||||
#endif
|
||||
if(pret < 0 &&
|
||||
if(pret < 0
|
||||
#ifndef USE_WINSOCK
|
||||
errno != EAGAIN && errno != EINTR &&
|
||||
&& errno != EAGAIN && errno != EINTR &&
|
||||
# ifdef EWOULDBLOCK
|
||||
errno != EWOULDBLOCK &&
|
||||
# endif
|
||||
errno != ENOBUFS
|
||||
#else
|
||||
WSAGetLastError() != WSAEINPROGRESS &&
|
||||
WSAGetLastError() != WSAEINTR &&
|
||||
WSAGetLastError() != WSAENOBUFS &&
|
||||
WSAGetLastError() != WSAEWOULDBLOCK
|
||||
errno != ENOMEM && errno != ENOBUFS
|
||||
#else /* USE_WINSOCK */
|
||||
/* Sleep does not error */
|
||||
#endif
|
||||
) {
|
||||
log_err("poll udp out timer failed: %s",
|
||||
|
|
|
|||
Loading…
Reference in a new issue