Use CLOCK_MONOTONIC for the rpc event loops
authorjca <jca@openbsd.org>
Thu, 14 Dec 2017 16:55:44 +0000 (16:55 +0000)
committerjca <jca@openbsd.org>
Thu, 14 Dec 2017 16:55:44 +0000 (16:55 +0000)
From Scott Cheloha, ok deraadt@ tb@

lib/libc/rpc/clnt_tcp.c
lib/libc/rpc/clnt_udp.c
lib/libc/rpc/svc_tcp.c

index a42572b..462e4ef 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: clnt_tcp.c,v 1.29 2015/11/01 03:45:29 guenther Exp $ */
+/*     $OpenBSD: clnt_tcp.c,v 1.30 2017/12/14 16:55:44 jca Exp $ */
 
 /*
  * Copyright (c) 2010, Oracle America, Inc.
@@ -385,25 +385,26 @@ static int
 readtcp(struct ct_data *ct, caddr_t buf, int len)
 {
        struct pollfd pfd[1];
-       struct timeval start, after, duration, tmp;
-       int delta, r, save_errno;
+       struct timespec start, after, duration, tmp, delta, wait;
+       int r, save_errno;
 
        if (len == 0)
                return (0);
 
        pfd[0].fd = ct->ct_sock;
        pfd[0].events = POLLIN;
-       delta = ct->ct_wait.tv_sec * 1000 + ct->ct_wait.tv_usec / 1000;
-       gettimeofday(&start, NULL);
+       TIMEVAL_TO_TIMESPEC(&ct->ct_wait, &wait);
+       delta = wait;
+       clock_gettime(CLOCK_MONOTONIC, &start);
        for (;;) {
-               r = poll(pfd, 1, delta);
+               r = ppoll(pfd, 1, &delta, NULL);
                save_errno = errno;
 
-               gettimeofday(&after, NULL);
-               timersub(&start, &after, &duration);
-               timersub(&ct->ct_wait, &duration, &tmp);
-               delta = tmp.tv_sec * 1000 + tmp.tv_usec / 1000;
-               if (delta <= 0)
+               clock_gettime(CLOCK_MONOTONIC, &after);
+               timespecsub(&start, &after, &duration);
+               timespecsub(&wait, &duration, &tmp);
+               delta = tmp;
+               if (delta.tv_sec < 0 || !timespecisset(&delta))
                        r = 0;
 
                switch (r) {
index 0f34d43..a90bb78 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: clnt_udp.c,v 1.32 2015/11/01 03:45:29 guenther Exp $ */
+/*     $OpenBSD: clnt_udp.c,v 1.33 2017/12/14 16:55:44 jca Exp $ */
 
 /*
  * Copyright (c) 2010, Oracle America, Inc.
@@ -216,19 +216,20 @@ clntudp_call(CLIENT *cl,  /* client handle */
        struct sockaddr_in from;
        struct rpc_msg reply_msg;
        XDR reply_xdrs;
-       struct timeval time_waited, start, after, tmp1, tmp2;
+       struct timespec time_waited, start, after, tmp1, tmp2, wait;
        bool_t ok;
        int nrefreshes = 2;     /* number of times to refresh cred */
-       struct timeval timeout;
+       struct timespec timeout;
 
        if (cu->cu_total.tv_usec == -1)
-               timeout = utimeout;     /* use supplied timeout */
+               TIMEVAL_TO_TIMESPEC(&utimeout, &timeout);     /* use supplied timeout */
        else
-               timeout = cu->cu_total; /* use default timeout */
+               TIMEVAL_TO_TIMESPEC(&cu->cu_total, &timeout); /* use default timeout */
 
        pfd[0].fd = cu->cu_sock;
        pfd[0].events = POLLIN;
-       timerclear(&time_waited);
+       timespecclear(&time_waited);
+       TIMEVAL_TO_TIMESPEC(&cu->cu_wait, &wait);
 call_again:
        xdrs = &(cu->cu_outxdrs);
        xdrs->x_op = XDR_ENCODE;
@@ -254,7 +255,7 @@ send_again:
        /*
         * Hack to provide rpc-based message passing
         */
-       if (!timerisset(&timeout))
+       if (!timespecisset(&timeout))
                return (cu->cu_error.re_status = RPC_TIMEDOUT);
 
        /*
@@ -266,14 +267,13 @@ send_again:
        reply_msg.acpted_rply.ar_results.where = resultsp;
        reply_msg.acpted_rply.ar_results.proc = xresults;
 
-       gettimeofday(&start, NULL);
+       clock_gettime(CLOCK_MONOTONIC, &start);
        for (;;) {
-               switch (poll(pfd, 1,
-                   cu->cu_wait.tv_sec * 1000 + cu->cu_wait.tv_usec / 1000)) {
+               switch (ppoll(pfd, 1, &wait, NULL)) {
                case 0:
-                       timeradd(&time_waited, &cu->cu_wait, &tmp1);
+                       timespecadd(&time_waited, &wait, &tmp1);
                        time_waited = tmp1;
-                       if (timercmp(&time_waited, &timeout, <))
+                       if (timespeccmp(&time_waited, &timeout, <))
                                goto send_again;
                        return (cu->cu_error.re_status = RPC_TIMEDOUT);
                case 1:
@@ -286,11 +286,11 @@ send_again:
                        /* FALLTHROUGH */
                case -1:
                        if (errno == EINTR) {
-                               gettimeofday(&after, NULL);
-                               timersub(&after, &start, &tmp1);
-                               timeradd(&time_waited, &tmp1, &tmp2);
+                               clock_gettime(CLOCK_MONOTONIC, &after);
+                               timespecsub(&after, &start, &tmp1);
+                               timespecadd(&time_waited, &tmp1, &tmp2);
                                time_waited = tmp2;
-                               if (timercmp(&time_waited, &timeout, <))
+                               if (timespeccmp(&time_waited, &timeout, <))
                                        continue;
                                return (cu->cu_error.re_status = RPC_TIMEDOUT);
                        }
index 8c2a3e0..fcecbfa 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: svc_tcp.c,v 1.37 2015/11/01 03:45:29 guenther Exp $ */
+/*     $OpenBSD: svc_tcp.c,v 1.38 2017/12/14 16:55:44 jca Exp $ */
 
 /*
  * Copyright (c) 2010, Oracle America, Inc.
@@ -321,7 +321,7 @@ svctcp_destroy(SVCXPRT *xprt)
  * All read operations timeout after 35 seconds.
  * A timeout is fatal for the connection.
  */
-static struct timeval wait_per_try = { 35, 0 };
+static struct timespec wait_per_try = { 35, 0 };
 
 /*
  * reads data from the tcp conection.
@@ -332,31 +332,30 @@ static int
 readtcp(SVCXPRT *xprt, caddr_t buf, int len)
 {
        int sock = xprt->xp_sock;
-       int delta, nready;
-       struct timeval start;
-       struct timeval tmp1, tmp2;
+       int nready;
+       struct timespec start, delta, tmp1, tmp2;
        struct pollfd pfd[1];
 
        /*
         * All read operations timeout after 35 seconds.
         * A timeout is fatal for the connection.
         */
-       delta = wait_per_try.tv_sec * 1000;
-       gettimeofday(&start, NULL);
+       delta = wait_per_try;
+       clock_gettime(CLOCK_MONOTONIC, &start);
        pfd[0].fd = sock;
        pfd[0].events = POLLIN;
        do {
-               nready = poll(pfd, 1, delta);
+               nready = ppoll(pfd, 1, &delta, NULL);
                switch (nready) {
                case -1:
                        if (errno != EINTR)
                                goto fatal_err;
-                       gettimeofday(&tmp1, NULL);
-                       timersub(&tmp1, &start, &tmp2);
-                       timersub(&wait_per_try, &tmp2, &tmp1);
-                       if (tmp1.tv_sec < 0 || !timerisset(&tmp1))
+                       clock_gettime(CLOCK_MONOTONIC, &tmp1);
+                       timespecsub(&tmp1, &start, &tmp2);
+                       timespecsub(&wait_per_try, &tmp2, &tmp1);
+                       if (tmp1.tv_sec < 0 || !timespecisset(&tmp1))
                                goto fatal_err;
-                       delta = tmp1.tv_sec * 1000 + tmp1.tv_usec / 1000;
+                       delta = tmp1;
                        continue;
                case 0:
                        goto fatal_err;