diff options
author | 2016-05-26 06:59:42 +0000 | |
---|---|---|
committer | 2016-05-26 06:59:42 +0000 | |
commit | eb76e4bcd6b77ed60e3ab89a12f927a3ac460942 (patch) | |
tree | b8c3885670aabbf4db63e08936df18cc6430cb4e /lib/libc | |
parent | Make format conversion routines return the number of frames (diff) | |
download | wireguard-openbsd-eb76e4bcd6b77ed60e3ab89a12f927a3ac460942.tar.xz wireguard-openbsd-eb76e4bcd6b77ed60e3ab89a12f927a3ac460942.zip |
Calculate elapsed time in poll() and subtract that from the remaining time
when restarting poll() after receiving a signal.
The ruby runtime send signals to threads periodically, so without accounting
for elapsed time, the timeout would never expire if we didn't get a response
from a nameserver.
ok deraadt@ eric@
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/asr/asr.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/lib/libc/asr/asr.c b/lib/libc/asr/asr.c index 36fd724e8cb..e39d60dc262 100644 --- a/lib/libc/asr/asr.c +++ b/lib/libc/asr/asr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: asr.c,v 1.51 2016/02/24 20:52:53 eric Exp $ */ +/* $OpenBSD: asr.c,v 1.52 2016/05/26 06:59:42 jmatthew Exp $ */ /* * Copyright (c) 2010-2012 Eric Faurot <eric@openbsd.org> * @@ -169,15 +169,30 @@ int asr_run_sync(struct asr_query *as, struct asr_result *ar) { struct pollfd fds[1]; - int r, saved_errno = errno; + struct timespec pollstart, pollend, elapsed; + int timeout, r, p, saved_errno = errno; while ((r = asr_run(as, ar)) == ASYNC_COND) { fds[0].fd = ar->ar_fd; fds[0].events = (ar->ar_cond == ASR_WANT_READ) ? POLLIN:POLLOUT; + + timeout = ar->ar_timeout; again: - r = poll(fds, 1, ar->ar_timeout); - if (r == -1 && errno == EINTR) + if (clock_gettime(CLOCK_MONOTONIC, &pollstart)) + break; + p = poll(fds, 1, timeout); + if (p == -1 && errno == EINTR) { + if (clock_gettime(CLOCK_MONOTONIC, &pollend)) + break; + + timespecsub(&pollend, &pollstart, &elapsed); + timeout -= (elapsed.tv_sec * 1000) + + (elapsed.tv_nsec / 1000000); + if (timeout < 1) + break; goto again; + } + /* * Otherwise, just ignore the error and let asr_run() * catch the failure. |