mirror of
https://github.com/golang/go
synced 2024-11-12 01:00:22 -07:00
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 <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
9473c044f1
commit
79c50c4d57
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user