This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Use monotonic timer for send_dg
- From: Kwok Cheung Yeung <kcy at codesourcery dot com>
- To: <libc-alpha at sourceware dot org>
- Date: Sat, 28 Mar 2015 15:16:59 +0000
- Subject: [PATCH] Use monotonic timer for send_dg
- Authentication-results: sourceware.org; auth=none
This patch addresses a rare scenario where a change in the system clock
may result in an incorrect timeout.
In send_dg (in resolv/res_send.c), eventually called from functions such
as getaddrinfo:
evNowTime(&now);
evConsTime(&timeout, seconds, 0);
evAddTime(&finish, &now, &timeout);
...
recompute_resend:
evNowTime(&now);
...
evSubTime(&timeout, &finish, &now);
...
ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
...
n = __poll (pfd, 1, ptimeout);
If in between the first and second calls to evNowTime the system clock
changes, then the updated value of timeout will also be modified (e.g.
if the time shifts back an hour, then the timeout would be extended by
an hour).
This patch addresses this by making evNowTime use a monotonic clock if
available, since it cannot go backwards in time. If not available, then
it falls back to using the realtime clock as before. I have run a full
'make xcheck' before and after, with no regressions found.
Kwok
Use monotonic timer for send_dg
* resolv/res_send.c: Include time.h instead of sys/time.h.
(evNowTime): Obtain current time from monotonic clock if possible.
---
resolv/res_send.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/resolv/res_send.c b/resolv/res_send.c
index c35fb66..b7176dd 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -76,7 +76,7 @@ static const char rcsid[] = "$BINDId: res_send.c,v
8.38 2000/03/30 20:16:51 vixi
#include <assert.h>
#include <sys/types.h>
#include <sys/param.h>
-#include <sys/time.h>
+#include <time.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/poll.h>
@@ -169,6 +169,11 @@ static void
evNowTime(struct timespec *res) {
struct timeval now;
+#ifdef _POSIX_MONOTONIC_CLOCK
+ if (clock_gettime(CLOCK_MONOTONIC, res) == 0)
+ return;
+#endif
+
if (gettimeofday(&now, NULL) < 0)
evConsTime(res, 0, 0);
else
--
2.3.4