]> Cypherpunks repositories - gostls13.git/commitdiff
net: return error from pollster rather than panicing
authorDave Cheney <dave@cheney.net>
Tue, 16 Oct 2012 22:41:00 +0000 (09:41 +1100)
committerDave Cheney <dave@cheney.net>
Tue, 16 Oct 2012 22:41:00 +0000 (09:41 +1100)
Fixes #3590.

R=bradfitz, mikioh.mikioh, iant, bsiegert
CC=golang-dev
https://golang.org/cl/6684054

src/pkg/net/fd_unix.go
src/pkg/net/fd_unix_test.go [new file with mode: 0644]

index c55f3362f0514df0be52ff75f4ea82d2f556c27b..e231c3e21290d39402a5d1007514bcc0ca4c92d3 100644 (file)
@@ -97,15 +97,11 @@ func (s *pollServer) AddFD(fd *netFD, mode int) error {
        }
 
        wake, err := s.poll.AddFD(intfd, mode, false)
+       s.Unlock()
        if err != nil {
-               panic("pollServer AddFD " + err.Error())
-       }
-       if wake {
-               doWakeup = true
+               return &OpError{"addfd", fd.net, fd.laddr, err}
        }
-       s.Unlock()
-
-       if doWakeup {
+       if wake || doWakeup {
                s.Wakeup()
        }
        return nil
diff --git a/src/pkg/net/fd_unix_test.go b/src/pkg/net/fd_unix_test.go
new file mode 100644 (file)
index 0000000..50befac
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright 2012 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.
+
+// +build darwin freebsd linux netbsd openbsd
+
+package net
+
+import (
+       "testing"
+)
+
+// Issue 3590. netFd.AddFD should return an error 
+// from the underlying pollster rather than panicing.
+func TestAddFDReturnsError(t *testing.T) {
+       l, err := Listen("tcp", "127.0.0.1:0")
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer l.Close()
+
+       go func() {
+               for {
+                       c, err := l.Accept()
+                       if err != nil {
+                               return
+                       }
+                       defer c.Close()
+               }
+       }()
+
+       c, err := Dial("tcp", l.Addr().String())
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer c.Close()
+
+       // replace c's pollServer with a closed version.
+       ps, err := newPollServer()
+       if err != nil {
+               t.Fatal(err)
+       }
+       ps.poll.Close()
+       c.(*TCPConn).conn.fd.pollServer = ps
+
+       var b [1]byte
+       _, err = c.Read(b[:])
+       if err, ok := err.(*OpError); ok {
+               if err.Op == "addfd" {
+                       return
+               }
+               if err, ok := err.Err.(*OpError); ok {
+                       // the err is sometimes wrapped by another OpError
+                       if err.Op == "addfd" {
+                               return
+                       }
+               }
+       }
+       t.Error(err)
+}