mirror of
https://github.com/golang/go.git
synced 2025-05-30 19:52:53 +00: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,25 +117,31 @@ func newFile(fd uintptr, name string, kind newFileKind) *File {
|
|||||||
|
|
||||||
pollable := kind == kindOpenFile || kind == kindPipe || kind == kindNonBlock
|
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),
|
// If the caller passed a non-blocking filedes (kindNonBlock),
|
||||||
// we assume they know what they are doing so we allow it to be
|
// we assume they know what they are doing so we allow it to be
|
||||||
// used with kqueue.
|
// used with kqueue.
|
||||||
if runtime.GOOS == "freebsd" && kind == kindOpenFile {
|
if kind == kindOpenFile {
|
||||||
|
var st syscall.Stat_t
|
||||||
|
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
|
pollable = false
|
||||||
}
|
}
|
||||||
|
case "darwin":
|
||||||
// On Darwin, kqueue does not work properly with fifos:
|
// 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
|
// closing the last writer does not cause a kqueue event
|
||||||
// for any readers. See issue #24164.
|
// for any readers. See issue #24164.
|
||||||
if runtime.GOOS == "darwin" && kind == kindOpenFile {
|
if err := syscall.Fstat(fdi, &st); err == nil && (st.Mode&syscall.S_IFMT == syscall.S_IFIFO || st.Mode&syscall.S_IFMT == syscall.S_IFREG) {
|
||||||
var st syscall.Stat_t
|
|
||||||
if err := syscall.Fstat(fdi, &st); err == nil && st.Mode&syscall.S_IFMT == syscall.S_IFIFO {
|
|
||||||
pollable = false
|
pollable = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := f.pfd.Init("file", pollable); err != nil {
|
if err := f.pfd.Init("file", pollable); err != nil {
|
||||||
// An error here indicates a failure to register
|
// An error here indicates a failure to register
|
||||||
|
Loading…
x
Reference in New Issue
Block a user