Commit 451a2eb0 authored by Mikio Hara's avatar Mikio Hara

runtime, internal/poll: report only critical event scanning error

This change makes the runtime-integrated network poller report only
critical event scanning errors.

In the previous attempt, CL 166497, we treated any combination of error
events as event scanning errors and it caused false positives in event
waiters because platform-dependent event notification mechanisms allow
event originators to use various combination of events.

To avoid false positives, this change makes the poller treat an
individual error event as a critical event scanning error by the
convention of event notification mechanism implementations.

Updates #30624.
Fixes #30817.
Fixes #30840.

Change-Id: I906c9e83864527ff73f636fd02bab854d54684ea
Reviewed-on: https://go-review.googlesource.com/c/go/+/167777
Run-TryBot: Mikio Hara <mikioh.public.networking@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent d24d25b4
......@@ -9,6 +9,7 @@ import (
"net"
"os"
"testing"
"time"
)
func TestReadError(t *testing.T) {
......@@ -18,6 +19,11 @@ func TestReadError(t *testing.T) {
t.Skip(err)
}
defer f.Close()
// Give scheduler a chance to have two separated
// goroutines: an event poller and an event waiter.
time.Sleep(100 * time.Millisecond)
var b [1]byte
_, err = f.Read(b[:])
if perr := parseReadError(err, isBadStateFileError); perr != nil {
......
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package poll_test
import (
"io/ioutil"
"os"
"runtime"
"sync"
"testing"
"time"
)
func TestRead(t *testing.T) {
t.Run("SpecialFile", func(t *testing.T) {
var wg sync.WaitGroup
for _, p := range specialFiles() {
for i := 0; i < 4; i++ {
wg.Add(1)
go func(p string) {
defer wg.Done()
for i := 0; i < 100; i++ {
if _, err := ioutil.ReadFile(p); err != nil {
t.Error(err)
return
}
time.Sleep(time.Nanosecond)
}
}(p)
}
}
wg.Wait()
})
}
func specialFiles() []string {
var ps []string
switch runtime.GOOS {
case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd":
ps = []string{
"/dev/null",
}
case "linux":
ps = []string{
"/dev/null",
"/proc/stat",
"/sys/devices/system/cpu/online",
}
}
nps := ps[:0]
for _, p := range ps {
f, err := os.Open(p)
if err != nil {
continue
}
f.Close()
nps = append(nps, p)
}
return nps
}
......@@ -233,7 +233,7 @@ retry:
println("*** netpollready i=", i, "revents=", pfd.revents, "events=", pfd.events, "pd=", pds[i])
}
pds[i].everr = false
if pfd.revents&_POLLERR != 0 {
if pfd.revents == _POLLERR {
pds[i].everr = true
}
netpollready(&toRun, pds[i], mode)
......
......@@ -92,7 +92,7 @@ retry:
if mode != 0 {
pd := *(**pollDesc)(unsafe.Pointer(&ev.data))
pd.everr = false
if ev.events&_EPOLLERR != 0 {
if ev.events == _EPOLLERR {
pd.everr = true
}
netpollready(&toRun, pd, mode)
......
......@@ -104,7 +104,7 @@ retry:
if mode != 0 {
pd := (*pollDesc)(unsafe.Pointer(ev.udata))
pd.everr = false
if ev.flags&_EV_ERROR != 0 {
if ev.flags == _EV_ERROR {
pd.everr = true
}
netpollready(&toRun, pd, mode)
......
......@@ -234,7 +234,7 @@ retry:
if mode != 0 {
pd.everr = false
if ev.portev_events&_POLLERR != 0 {
if ev.portev_events == _POLLERR {
pd.everr = true
}
netpollready(&toRun, pd, mode)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment