From 0abb6b668c708aa84daba4b036e536fd76a8b1c5 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Sat, 12 Oct 2019 00:46:13 -0700 Subject: rwcancel: handle EINTR and EAGAIN in unixSelect() On my Chromebook (Linux 4.19.44 in a VM) and on an AWS EC2 machine, select() was sometimes returning EINTR. This is harmless and just means you should try again. So let's try again. This eliminates a problem where the tunnel fails to come up correctly and the program needs to be restarted. Signed-off-by: Avery Pennarun --- rwcancel/rwcancel.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/rwcancel/rwcancel.go b/rwcancel/rwcancel.go index 62397c2..808e691 100644 --- a/rwcancel/rwcancel.go +++ b/rwcancel/rwcancel.go @@ -60,7 +60,13 @@ func (rw *RWCancel) ReadyRead() bool { fdset := fdSet{} fdset.set(rw.fd) fdset.set(closeFd) - err := unixSelect(max(rw.fd, closeFd)+1, &fdset.FdSet, nil, nil, nil) + var err error + for { + err = unixSelect(max(rw.fd, closeFd)+1, &fdset.FdSet, nil, nil, nil) + if err == nil || !RetryAfterError(err) { + break + } + } if err != nil { return false } @@ -75,7 +81,13 @@ func (rw *RWCancel) ReadyWrite() bool { fdset := fdSet{} fdset.set(rw.fd) fdset.set(closeFd) - err := unixSelect(max(rw.fd, closeFd)+1, nil, &fdset.FdSet, nil, nil) + var err error + for { + err = unixSelect(max(rw.fd, closeFd)+1, nil, &fdset.FdSet, nil, nil) + if err == nil || !RetryAfterError(err) { + break + } + } if err != nil { return false } -- cgit v1.2.3-59-g8ed1b