From a9b377e9e10eb5194c0bdff32136c11b17253bfd Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 20 May 2021 17:42:34 +0200 Subject: [PATCH] rwcancel: use poll instead of select Suggested-by: Lennart Poettering Signed-off-by: Jason A. Donenfeld --- rwcancel/fdset.go | 24 ------------------------ rwcancel/rwcancel.go | 33 ++++++++++++--------------------- rwcancel/select_default.go | 15 --------------- rwcancel/select_linux.go | 13 ------------- 4 files changed, 12 insertions(+), 73 deletions(-) delete mode 100644 rwcancel/fdset.go delete mode 100644 rwcancel/select_default.go delete mode 100644 rwcancel/select_linux.go diff --git a/rwcancel/fdset.go b/rwcancel/fdset.go deleted file mode 100644 index 2c5ca9e..0000000 --- a/rwcancel/fdset.go +++ /dev/null @@ -1,24 +0,0 @@ -// +build !windows - -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2017-2021 WireGuard LLC. All Rights Reserved. - */ - -package rwcancel - -import "golang.org/x/sys/unix" - -type fdSet struct { - unix.FdSet -} - -func (fdset *fdSet) set(i int) { - bits := 32 << (^uint(0) >> 63) - fdset.Bits[i/bits] |= 1 << uint(i%bits) -} - -func (fdset *fdSet) check(i int) bool { - bits := 32 << (^uint(0) >> 63) - return (fdset.Bits[i/bits] & (1 << uint(i%bits))) != 0 -} diff --git a/rwcancel/rwcancel.go b/rwcancel/rwcancel.go index 70eb4ca..05484e1 100644 --- a/rwcancel/rwcancel.go +++ b/rwcancel/rwcancel.go @@ -17,13 +17,6 @@ import ( "golang.org/x/sys/unix" ) -func max(a, b int) int { - if a > b { - return a - } - return b -} - type RWCancel struct { fd int closingReader *os.File @@ -50,13 +43,12 @@ func RetryAfterError(err error) bool { } func (rw *RWCancel) ReadyRead() bool { - closeFd := int(rw.closingReader.Fd()) - fdset := fdSet{} - fdset.set(rw.fd) - fdset.set(closeFd) + closeFd := int32(rw.closingReader.Fd()) + + pollFds := []unix.PollFd{{Fd: int32(rw.fd), Events: unix.POLLIN}, {Fd: closeFd, Events: unix.POLLIN}} var err error for { - err = unixSelect(max(rw.fd, closeFd)+1, &fdset.FdSet, nil, nil, nil) + _, err = unix.Poll(pollFds, -1) if err == nil || !RetryAfterError(err) { break } @@ -64,20 +56,18 @@ func (rw *RWCancel) ReadyRead() bool { if err != nil { return false } - if fdset.check(closeFd) { + if pollFds[1].Revents != 0 { return false } - return fdset.check(rw.fd) + return pollFds[0].Revents != 0 } func (rw *RWCancel) ReadyWrite() bool { - closeFd := int(rw.closingReader.Fd()) - fdset := fdSet{} - fdset.set(rw.fd) - fdset.set(closeFd) + closeFd := int32(rw.closingReader.Fd()) + pollFds := []unix.PollFd{{Fd: int32(rw.fd), Events: unix.POLLOUT}, {Fd: closeFd, Events: unix.POLLOUT}} var err error for { - err = unixSelect(max(rw.fd, closeFd)+1, nil, &fdset.FdSet, nil, nil) + _, err = unix.Poll(pollFds, -1) if err == nil || !RetryAfterError(err) { break } @@ -85,10 +75,11 @@ func (rw *RWCancel) ReadyWrite() bool { if err != nil { return false } - if fdset.check(closeFd) { + + if pollFds[1].Revents != 0 { return false } - return fdset.check(rw.fd) + return pollFds[0].Revents != 0 } func (rw *RWCancel) Read(p []byte) (n int, err error) { diff --git a/rwcancel/select_default.go b/rwcancel/select_default.go deleted file mode 100644 index 990de83..0000000 --- a/rwcancel/select_default.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build !linux,!windows - -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2017-2021 WireGuard LLC. All Rights Reserved. - */ - -package rwcancel - -import "golang.org/x/sys/unix" - -func unixSelect(nfd int, r *unix.FdSet, w *unix.FdSet, e *unix.FdSet, timeout *unix.Timeval) error { - _, err := unix.Select(nfd, r, w, e, timeout) - return err -} diff --git a/rwcancel/select_linux.go b/rwcancel/select_linux.go deleted file mode 100644 index ac941fd..0000000 --- a/rwcancel/select_linux.go +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2017-2021 WireGuard LLC. All Rights Reserved. - */ - -package rwcancel - -import "golang.org/x/sys/unix" - -func unixSelect(nfd int, r *unix.FdSet, w *unix.FdSet, e *unix.FdSet, timeout *unix.Timeval) (err error) { - _, err = unix.Select(nfd, r, w, e, timeout) - return -}