Skip to content

Commit

Permalink
http: don't fail on accept hitting EMFILE
Browse files Browse the repository at this point in the history
Fixes #1891

R=rsc
CC=golang-dev
https://golang.org/cl/4550112
  • Loading branch information
bradfitz committed Jun 3, 2011
1 parent 0015e8e commit 2655757
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
37 changes: 37 additions & 0 deletions src/pkg/http/serve_test.go
Expand Up @@ -18,6 +18,7 @@ import (
"net"
"reflect"
"strings"
"syscall"
"testing"
"time"
)
Expand Down Expand Up @@ -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) {
Expand Down
4 changes: 4 additions & 0 deletions src/pkg/http/server.go
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/pkg/os/error_posix.go
Expand Up @@ -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 {
Expand Down

0 comments on commit 2655757

Please sign in to comment.