Skip to content

Commit 4a1a5d1

Browse files
committed
Handling EINTR on linux epoll in case of timeout
Adding read timeout so that test won't hang
1 parent 23fef4a commit 4a1a5d1

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

ext/socket/selector-epoll.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,14 @@ static SgObject wait_selector(unix_context_t *ctx, int nsock,
8787

8888
evm = SG_NEW_ATOMIC2(struct epoll_event *, n * sizeof(struct epoll_event));
8989
c = epoll_wait(ctx->fd, evm, n, millis);
90+
/*
91+
EINTR The call was interrupted by a signal handler before either
92+
(1) any of the requested events occurred or (2) the
93+
timeout expired; see signal(7).
9094
91-
if (c < 0) {
95+
So, timeout is also EINTR which we do put.
96+
*/
97+
if (c < 0 && errno != EINTR) {
9298
*err = errno;
9399
return SG_FALSE;
94100
}

ext/socket/test.scm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@
451451
(lambda ()
452452
(let ((s (make-client-socket "localhost" (server-service server)))
453453
(msg (string->utf8 (string-append "hello " (number->string i)))))
454+
(socket-set-read-timeout! s 100) ;; 100ms
454455
(thread-sleep! delay)
455456
(guard (e (else #t))
456457
(socket-send s msg)
@@ -477,9 +478,11 @@
477478
(socket-close server)
478479

479480
(values (atomic-fixnum-load result) (atomic-fixnum-load result-to)))
481+
480482
(let-values (((r rt) (selector-test 500)))
481483
(test-equal "no timeout (received)" 500 r)
482484
(test-equal "no timeout (timedout)" 0 rt))
485+
483486
(let-values (((r rt) (selector-test 500 (duration:of-nanos 1))))
484487
;; for some reason, some sockets don't timeout.
485488
(test-assert "with timeout (received)" (< r 500))

0 commit comments

Comments
 (0)