net: fix inconsistent error values on Accept

This change fixes inconsistent error values on Accept{,TCP,Unix}.

Updates #4856.

Change-Id: Ie3bb534c19a724cacb3ea3f3656e46c810b2123f
Reviewed-on: https://go-review.googlesource.com/8996
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Mikio Hara 2015-04-17 14:35:54 +09:00
parent 310db63c5b
commit 4540e162b1
7 changed files with 109 additions and 32 deletions

View file

@ -11,6 +11,7 @@ import (
"os"
"runtime"
"testing"
"time"
)
func isTimeoutError(err error) bool {
@ -424,3 +425,76 @@ func TestCloseError(t *testing.T) {
}
}
}
// parseAcceptError parses nestedErr and reports whether it is a valid
// error value from Accept functions.
// It returns nil when nestedErr is valid.
func parseAcceptError(nestedErr error) error {
if nestedErr == nil {
return nil
}
switch err := nestedErr.(type) {
case *OpError:
if err := err.isValid(); err != nil {
return err
}
nestedErr = err.Err
goto second
}
return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
second:
if isPlatformError(nestedErr) {
return nil
}
switch err := nestedErr.(type) {
case *os.SyscallError:
nestedErr = err.Err
goto third
}
switch nestedErr {
case errClosing, errTimeout:
return nil
}
return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
third:
if isPlatformError(nestedErr) {
return nil
}
return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
}
func TestAcceptError(t *testing.T) {
handler := func(ls *localServer, ln Listener) {
for {
ln.(*TCPListener).SetDeadline(time.Now().Add(5 * time.Millisecond))
c, err := ln.Accept()
if perr := parseAcceptError(err); perr != nil {
t.Error(perr)
}
if err != nil {
if c != nil {
t.Errorf("Accept returned non-nil interface %T(%v) with err != nil", c, c)
}
if !isTimeoutError(err) && !isTemporaryError(err) {
return
}
continue
}
c.Close()
}
}
ls, err := newLocalServer("tcp")
if err != nil {
t.Fatal(err)
}
if err := ls.buildup(handler); err != nil {
ls.teardown()
t.Fatal(err)
}
time.Sleep(100 * time.Millisecond)
ls.teardown()
}