]> Cypherpunks repositories - gostls13.git/commitdiff
os: disable the use of netpoll on regular files on *BSDs.
authorYuval Pavel Zholkover <paulzhol@gmail.com>
Mon, 7 Jan 2019 00:06:38 +0000 (02:06 +0200)
committerIan Lance Taylor <iant@golang.org>
Wed, 9 Jan 2019 05:04:26 +0000 (05:04 +0000)
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>
src/os/file_unix.go

index 688b68e1c3547cff7466f082bcfa04839fcdb2d6..c91efa818542bb34b51c6155ce0d66f64c8769de 100644 (file)
@@ -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
+                       }
                }
        }