From: Avery Pennarun Date: Sat, 12 Oct 2019 07:46:13 +0000 (-0700) Subject: rwcancel: handle EINTR and EAGAIN in unixSelect() X-Git-Tag: 0.0.20200121~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0abb6b668c708aa84daba4b036e536fd76a8b1c5;p=thirdparty%2Fwireguard-go.git 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 --- 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 }