mirror of
https://github.com/golang/go
synced 2024-11-19 14:44:40 -07:00
http: don't fail on accept hitting EMFILE
Fixes #1891 R=rsc CC=golang-dev https://golang.org/cl/4550112
This commit is contained in:
parent
0015e8eb5e
commit
2655757900
@ -18,6 +18,7 @@ import (
|
||||
"net"
|
||||
"reflect"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@ -773,6 +774,42 @@ func TestHandlerPanic(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type errorListener struct {
|
||||
errs []os.Error
|
||||
}
|
||||
|
||||
func (l *errorListener) Accept() (c net.Conn, err os.Error) {
|
||||
if len(l.errs) == 0 {
|
||||
return nil, os.EOF
|
||||
}
|
||||
err = l.errs[0]
|
||||
l.errs = l.errs[1:]
|
||||
return
|
||||
}
|
||||
|
||||
func (l *errorListener) Close() os.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *errorListener) Addr() net.Addr {
|
||||
return dummyAddr("test-address")
|
||||
}
|
||||
|
||||
func TestAcceptMaxFds(t *testing.T) {
|
||||
log.SetOutput(ioutil.Discard) // is noisy otherwise
|
||||
defer log.SetOutput(os.Stderr)
|
||||
|
||||
ln := &errorListener{[]os.Error{
|
||||
&net.OpError{
|
||||
Op: "accept",
|
||||
Error: os.Errno(syscall.EMFILE),
|
||||
}}}
|
||||
err := Serve(ln, HandlerFunc(HandlerFunc(func(ResponseWriter, *Request) {})))
|
||||
if err != os.EOF {
|
||||
t.Errorf("got error %v, want EOF", err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkClientServer(b *testing.B) {
|
||||
b.StopTimer()
|
||||
ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
|
||||
|
@ -860,6 +860,10 @@ func (srv *Server) Serve(l net.Listener) os.Error {
|
||||
for {
|
||||
rw, e := l.Accept()
|
||||
if e != nil {
|
||||
if ne, ok := e.(net.Error); ok && ne.Temporary() {
|
||||
log.Printf("http: Accept error: %v", e)
|
||||
continue
|
||||
}
|
||||
return e
|
||||
}
|
||||
if srv.ReadTimeout != 0 {
|
||||
|
@ -13,7 +13,7 @@ type Errno int64
|
||||
func (e Errno) String() string { return syscall.Errstr(int(e)) }
|
||||
|
||||
func (e Errno) Temporary() bool {
|
||||
return e == Errno(syscall.EINTR) || e.Timeout()
|
||||
return e == Errno(syscall.EINTR) || e == Errno(syscall.EMFILE) || e.Timeout()
|
||||
}
|
||||
|
||||
func (e Errno) Timeout() bool {
|
||||
|
Loading…
Reference in New Issue
Block a user