Skip to content

Commit 010e0b7

Browse files
authored
Merge pull request fatih#20 from lrita/v2.0.0
fixes data-race between Get() and Close() of channelPool
2 parents 7e0c3ab + 12d582f commit 010e0b7

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

channel.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,19 @@ func NewChannelPool(initialCap, maxCap int, factory Factory) (Pool, error) {
5050
return c, nil
5151
}
5252

53-
func (c *channelPool) getConns() chan net.Conn {
53+
func (c *channelPool) getConnsAndFactory() (chan net.Conn, Factory) {
5454
c.mu.Lock()
5555
conns := c.conns
56+
factory := c.factory
5657
c.mu.Unlock()
57-
return conns
58+
return conns, factory
5859
}
5960

6061
// Get implements the Pool interfaces Get() method. If there is no new
6162
// connection available in the pool, a new connection will be created via the
6263
// Factory() method.
6364
func (c *channelPool) Get() (net.Conn, error) {
64-
conns := c.getConns()
65+
conns, factory := c.getConnsAndFactory()
6566
if conns == nil {
6667
return nil, ErrClosed
6768
}
@@ -76,7 +77,7 @@ func (c *channelPool) Get() (net.Conn, error) {
7677

7778
return c.wrapConn(conn), nil
7879
default:
79-
conn, err := c.factory()
80+
conn, err := factory()
8081
if err != nil {
8182
return nil, err
8283
}
@@ -128,4 +129,7 @@ func (c *channelPool) Close() {
128129
}
129130
}
130131

131-
func (c *channelPool) Len() int { return len(c.getConns()) }
132+
func (c *channelPool) Len() int {
133+
conns, _ := c.getConnsAndFactory()
134+
return len(conns)
135+
}

channel_test.go

+18
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,24 @@ func TestPoolConcurrent2(t *testing.T) {
249249
wg.Wait()
250250
}
251251

252+
func TestPoolConcurrent3(t *testing.T) {
253+
p, _ := NewChannelPool(0, 1, factory)
254+
255+
var wg sync.WaitGroup
256+
257+
wg.Add(1)
258+
go func() {
259+
p.Close()
260+
wg.Done()
261+
}()
262+
263+
if conn, err := p.Get(); err == nil {
264+
conn.Close()
265+
}
266+
267+
wg.Wait()
268+
}
269+
252270
func newChannelPool() (Pool, error) {
253271
return NewChannelPool(InitialCap, MaximumCap, factory)
254272
}

0 commit comments

Comments
 (0)