From: Yuval Pavel Zholkover Date: Mon, 7 Jan 2019 00:06:38 +0000 (+0200) Subject: os: disable the use of netpoll on regular files on *BSDs. X-Git-Tag: go1.12beta2~13 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=79c50c4d5728d785485fce8c75b9c2b2f93641ea;p=gostls13.git os: disable the use of netpoll on regular files on *BSDs. The kqueue based netpoller always registers file descriptors with EVFILT_READ and EVFILT_WRITE. However only EVFILT_READ notification is supported for regular files. On FreeBSD a regular file is always reported as ready for writing, resulting in a busy wait. On Darwin, Dragonfly, NetBSD and OpenBSD, a regular file is reported as ready for both reading and writing only once. Updates #19093 Change-Id: If284341f60c6c2332fb5499637d4cfa7a4e26b7b Reviewed-on: https://go-review.googlesource.com/c/156379 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- diff --git a/src/os/file_unix.go b/src/os/file_unix.go index 688b68e1c3..c91efa8185 100644 --- a/src/os/file_unix.go +++ b/src/os/file_unix.go @@ -117,23 +117,29 @@ func newFile(fd uintptr, name string, kind newFileKind) *File { pollable := kind == kindOpenFile || kind == kindPipe || kind == kindNonBlock - // Don't try to use kqueue with regular files on FreeBSD. - // It crashes the system unpredictably while running all.bash. - // Issue 19093. // If the caller passed a non-blocking filedes (kindNonBlock), // we assume they know what they are doing so we allow it to be // used with kqueue. - if runtime.GOOS == "freebsd" && kind == kindOpenFile { - pollable = false - } - - // On Darwin, kqueue does not work properly with fifos: - // closing the last writer does not cause a kqueue event - // for any readers. See issue #24164. - if runtime.GOOS == "darwin" && kind == kindOpenFile { + if kind == kindOpenFile { var st syscall.Stat_t - if err := syscall.Fstat(fdi, &st); err == nil && st.Mode&syscall.S_IFMT == syscall.S_IFIFO { - pollable = false + switch runtime.GOOS { + // Don't try to use kqueue with regular files on *BSDs. + // on FreeBSD with older kernels it used to crash the system unpredictably while running all.bash. + // while with newer kernels a regular file is always reported as ready for writing. + // on Dragonfly, NetBSD and OpenBSD the fd is signaled only once as ready (both read and write). + // Issue 19093. + case "dragonfly", "freebsd", "netbsd", "openbsd": + if err := syscall.Fstat(fdi, &st); err == nil && st.Mode&syscall.S_IFMT == syscall.S_IFREG { + pollable = false + } + case "darwin": + // In addition to the behavior described above for regular files, + // on Darwin, kqueue does not work properly with fifos: + // closing the last writer does not cause a kqueue event + // for any readers. See issue #24164. + if err := syscall.Fstat(fdi, &st); err == nil && (st.Mode&syscall.S_IFMT == syscall.S_IFIFO || st.Mode&syscall.S_IFMT == syscall.S_IFREG) { + pollable = false + } } }