mirror of
https://github.com/golang/go
synced 2024-09-18 15:32:18 +00:00
net/rpc: do not leak client socket on closed connection
Fixes #6897. LGTM=bradfitz R=golang-codereviews, bradfitz, r, rsc CC=golang-codereviews https://golang.org/cl/91230045
This commit is contained in:
parent
91a576eb0f
commit
82ca308743
|
@ -39,14 +39,16 @@ type Call struct {
|
|||
// with a single Client, and a Client may be used by
|
||||
// multiple goroutines simultaneously.
|
||||
type Client struct {
|
||||
mutex sync.Mutex // protects pending, seq, request
|
||||
sending sync.Mutex
|
||||
codec ClientCodec
|
||||
|
||||
sending sync.Mutex
|
||||
|
||||
mutex sync.Mutex // protects following
|
||||
request Request
|
||||
seq uint64
|
||||
codec ClientCodec
|
||||
pending map[uint64]*Call
|
||||
closing bool
|
||||
shutdown bool
|
||||
closing bool // user has called Close
|
||||
shutdown bool // server has told us to stop
|
||||
}
|
||||
|
||||
// A ClientCodec implements writing of RPC requests and
|
||||
|
@ -274,7 +276,7 @@ func Dial(network, address string) (*Client, error) {
|
|||
|
||||
func (client *Client) Close() error {
|
||||
client.mutex.Lock()
|
||||
if client.shutdown || client.closing {
|
||||
if client.closing {
|
||||
client.mutex.Unlock()
|
||||
return ErrShutdown
|
||||
}
|
||||
|
|
36
src/pkg/net/rpc/client_test.go
Normal file
36
src/pkg/net/rpc/client_test.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type shutdownCodec struct {
|
||||
responded chan int
|
||||
closed bool
|
||||
}
|
||||
|
||||
func (c *shutdownCodec) WriteRequest(*Request, interface{}) error { return nil }
|
||||
func (c *shutdownCodec) ReadResponseBody(interface{}) error { return nil }
|
||||
func (c *shutdownCodec) ReadResponseHeader(*Response) error {
|
||||
c.responded <- 1
|
||||
return errors.New("shutdownCodec ReadResponseHeader")
|
||||
}
|
||||
func (c *shutdownCodec) Close() error {
|
||||
c.closed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestCloseCodec(t *testing.T) {
|
||||
codec := &shutdownCodec{responded: make(chan int)}
|
||||
client := NewClientWithCodec(codec)
|
||||
<-codec.responded
|
||||
client.Close()
|
||||
if !codec.closed {
|
||||
t.Error("client.Close did not close codec")
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue