aboutsummaryrefslogtreecommitdiff
path: root/contrib/unbound/util/tube.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/unbound/util/tube.c')
-rw-r--r--contrib/unbound/util/tube.c78
1 files changed, 69 insertions, 9 deletions
diff --git a/contrib/unbound/util/tube.c b/contrib/unbound/util/tube.c
index 40556e72020b..96187e134e2f 100644
--- a/contrib/unbound/util/tube.c
+++ b/contrib/unbound/util/tube.c
@@ -45,6 +45,9 @@
#include "util/netevent.h"
#include "util/fptr_wlist.h"
#include "util/ub_event.h"
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
#ifndef USE_WINSOCK
/* on unix */
@@ -396,20 +399,28 @@ int tube_read_msg(struct tube* tube, uint8_t** buf, uint32_t* len,
return 1;
}
-/** perform a select() on the fd */
+/** perform poll() on the fd */
static int
pollit(int fd, struct timeval* t)
{
- fd_set r;
+ struct pollfd fds;
+ int pret;
+ int msec = -1;
+ memset(&fds, 0, sizeof(fds));
+ fds.fd = fd;
+ fds.events = POLLIN | POLLERR | POLLHUP;
#ifndef S_SPLINT_S
- FD_ZERO(&r);
- FD_SET(FD_SET_T fd, &r);
+ if(t)
+ msec = t->tv_sec*1000 + t->tv_usec/1000;
#endif
- if(select(fd+1, &r, NULL, NULL, t) == -1) {
+
+ pret = poll(&fds, 1, msec);
+
+ if(pret == -1)
return 0;
- }
- errno = 0;
- return (int)(FD_ISSET(fd, &r));
+ if(pret != 0)
+ return 1;
+ return 0;
}
int tube_poll(struct tube* tube)
@@ -424,6 +435,31 @@ int tube_wait(struct tube* tube)
return pollit(tube->sr, NULL);
}
+int tube_wait_timeout(struct tube* tube, int msec)
+{
+ int ret = 0;
+
+ while(1) {
+ struct pollfd fds;
+ memset(&fds, 0, sizeof(fds));
+
+ fds.fd = tube->sr;
+ fds.events = POLLIN | POLLERR | POLLHUP;
+ ret = poll(&fds, 1, msec);
+
+ if(ret == -1) {
+ if(errno == EAGAIN || errno == EINTR)
+ continue;
+ return -1;
+ }
+ break;
+ }
+
+ if(ret != 0)
+ return 1;
+ return 0;
+}
+
int tube_read_fd(struct tube* tube)
{
return tube->sr;
@@ -507,6 +543,7 @@ struct tube* tube_create(void)
if(tube->event == WSA_INVALID_EVENT) {
free(tube);
log_err("WSACreateEvent: %s", wsa_strerror(WSAGetLastError()));
+ return NULL;
}
if(!WSAResetEvent(tube->event)) {
log_err("WSAResetEvent: %s", wsa_strerror(WSAGetLastError()));
@@ -547,7 +584,10 @@ void tube_close_write(struct tube* ATTR_UNUSED(tube))
void tube_remove_bg_listen(struct tube* tube)
{
verbose(VERB_ALGO, "tube remove_bg_listen");
- ub_winsock_unregister_wsaevent(tube->ev_listen);
+ if (tube->ev_listen != NULL) {
+ ub_winsock_unregister_wsaevent(tube->ev_listen);
+ tube->ev_listen = NULL;
+ }
}
void tube_remove_bg_write(struct tube* tube)
@@ -649,6 +689,26 @@ int tube_wait(struct tube* tube)
return 1;
}
+int tube_wait_timeout(struct tube* tube, int msec)
+{
+ /* block on eventhandle */
+ DWORD res = WSAWaitForMultipleEvents(
+ 1 /* one event in array */,
+ &tube->event /* the event to wait for, our pipe signal */,
+ 0 /* wait for all events is false */,
+ msec /* wait for timeout */,
+ 0 /* we are not alertable for IO completion routines */
+ );
+ if(res == WSA_WAIT_TIMEOUT) {
+ return 0;
+ }
+ if(res == WSA_WAIT_IO_COMPLETION) {
+ /* a bit unexpected, since we were not alertable */
+ return -1;
+ }
+ return 1;
+}
+
int tube_read_fd(struct tube* ATTR_UNUSED(tube))
{
/* nothing sensible on Windows */