]> Cypherpunks repositories - gostls13.git/commitdiff
net/rpc: don't exit if Accept gets an error
authorRob Pike <r@golang.org>
Wed, 2 Sep 2015 23:05:04 +0000 (16:05 -0700)
committerRob Pike <r@golang.org>
Thu, 3 Sep 2015 21:17:08 +0000 (21:17 +0000)
The default implementation of Accept, which spins up a new server
for every new connection, calls log.Fatal if the listener is closed,
stopping any outstanding work. Change that to a non-fatal log
call so work can continue.

There is no programmatic signaling of the problem, just the log,
but that should be enough.

Fixes #11221.

Change-Id: I7c7f6164a0a0143236729eb778d7638c51c34ed1
Reviewed-on: https://go-review.googlesource.com/14185
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/net/rpc/server.go
src/net/rpc/server_test.go

index 6e6e881917494effee20b2deae4d1057523bac97..c4d4479958adc781e3dbc0c600130156c784d01d 100644 (file)
@@ -611,13 +611,15 @@ func (server *Server) readRequestHeader(codec ServerCodec) (service *service, mt
 }
 
 // Accept accepts connections on the listener and serves requests
-// for each incoming connection.  Accept blocks; the caller typically
-// invokes it in a go statement.
+// for each incoming connection. Accept blocks until the listener
+// returns a non-nil error. The caller typically invokes Accept in a
+// go statement.
 func (server *Server) Accept(lis net.Listener) {
        for {
                conn, err := lis.Accept()
                if err != nil {
-                       log.Fatal("rpc.Serve: accept:", err.Error()) // TODO(r): exit?
+                       log.Print("rpc.Serve: accept:", err.Error())
+                       return
                }
                go server.ServeConn(conn)
        }
index 0dc4ddc2de01cb0e130b0f569e13f16e1c21646f..498217b6ed69e6a50fe8c863e9e7f7e9058bbebf 100644 (file)
@@ -593,6 +593,19 @@ func TestErrorAfterClientClose(t *testing.T) {
        }
 }
 
+// Tests the fix to issue 11221. Without the fix, this loops forever or crashes.
+func TestAcceptExitAfterListenerClose(t *testing.T) {
+       newServer = NewServer()
+       newServer.Register(new(Arith))
+       newServer.RegisterName("net.rpc.Arith", new(Arith))
+       newServer.RegisterName("newServer.Arith", new(Arith))
+
+       var l net.Listener
+       l, newServerAddr = listenTCP()
+       l.Close()
+       newServer.Accept(l)
+}
+
 func benchmarkEndToEnd(dial func() (*Client, error), b *testing.B) {
        once.Do(startServer)
        client, err := dial()