From af20bb6830700041626bdae8e8eb7c4a838ac55e Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 26 Jun 2015 13:13:55 +0200 Subject: [PATCH] test: retry select() on EINTR, honor milliseconds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the test runner code that waits for other processes to terminate retry the select() system call on EINTR and take elapsed time into account. A small side effect of this change is that millisecond timeout values are now honored. PR-URL: https://github.com/libuv/libuv/pull/410 Reviewed-By: Saúl Ibarra Corretgé --- test/runner-unix.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/test/runner-unix.c b/test/runner-unix.c index 5da720fad..34de6dc25 100644 --- a/test/runner-unix.c +++ b/test/runner-unix.c @@ -37,6 +37,7 @@ #include #include +#include #include @@ -173,6 +174,8 @@ int process_wait(process_info_t* vec, int n, int timeout) { process_info_t* p; dowait_args args; pthread_t tid; + unsigned int elapsed_ms; + struct timeval timebase; struct timeval tv; fd_set fds; @@ -206,13 +209,37 @@ int process_wait(process_info_t* vec, int n, int timeout) { goto terminate; } - tv.tv_sec = timeout / 1000; - tv.tv_usec = 0; + if (gettimeofday(&timebase, NULL)) + abort(); - FD_ZERO(&fds); - FD_SET(args.pipe[0], &fds); + tv = timebase; + for (;;) { + /* Check that gettimeofday() doesn't jump back in time. */ + assert(tv.tv_sec == timebase.tv_sec || + (tv.tv_sec == timebase.tv_sec && tv.tv_usec >= timebase.tv_usec)); - r = select(args.pipe[0] + 1, &fds, NULL, NULL, &tv); + elapsed_ms = + (tv.tv_sec - timebase.tv_sec) * 1000 + + (tv.tv_usec / 1000) - + (timebase.tv_usec / 1000); + + r = 0; /* Timeout. */ + if (elapsed_ms >= (unsigned) timeout) + break; + + tv.tv_sec = (timeout - elapsed_ms) / 1000; + tv.tv_usec = (timeout - elapsed_ms) % 1000 * 1000; + + FD_ZERO(&fds); + FD_SET(args.pipe[0], &fds); + + r = select(args.pipe[0] + 1, &fds, NULL, NULL, &tv); + if (!(r == -1 && errno == EINTR)) + break; + + if (gettimeofday(&tv, NULL)) + abort(); + } if (r == -1) { perror("select()");