@@ -12,16 +12,21 @@ var (
1212 errPoolClosed = errors .New ("rethinkdb: pool is closed" )
1313)
1414
15+ const (
16+ poolIsNotClosed int32 = 0
17+ poolIsClosed int32 = 1
18+ )
19+
1520// A Pool is used to store a pool of connections to a single RethinkDB server
1621type Pool struct {
1722 host Host
1823 opts * ConnectOpts
1924
2025 conns []* Connection
2126 pointer int32
27+ closed int32
2228
23- mu sync.RWMutex // protects following fields
24- closed bool
29+ mu sync.Mutex // protects lazy creating connections
2530}
2631
2732// NewPool creates a new connection pool for the given host
@@ -40,7 +45,7 @@ func NewPool(host Host, opts *ConnectOpts) (*Pool, error) {
4045
4146 conns := make ([]* Connection , maxOpen )
4247 var err error
43- for i := range conns {
48+ for i := 0 ; i < opts . InitialCap ; i ++ {
4449 conns [i ], err = NewConnection (host .String (), opts )
4550 if err != nil {
4651 return nil , err
@@ -52,6 +57,7 @@ func NewPool(host Host, opts *ConnectOpts) (*Pool, error) {
5257 pointer : - 1 ,
5358 host : host ,
5459 opts : opts ,
60+ closed : poolIsNotClosed ,
5561 }, nil
5662}
5763
@@ -67,11 +73,17 @@ func (p *Pool) Ping() error {
6773// It is rare to Close a Pool, as the Pool handle is meant to be
6874// long-lived and shared between many goroutines.
6975func (p * Pool ) Close () error {
70- p .mu .RLock ()
71- defer p .mu .RUnlock ()
72- if p .closed {
76+ if atomic .LoadInt32 (& p .closed ) == poolIsClosed {
77+ return nil
78+ }
79+
80+ p .mu .Lock ()
81+ defer p .mu .Unlock ()
82+
83+ if p .closed == poolIsClosed {
7384 return nil
7485 }
86+ p .closed = poolIsClosed
7587
7688 for _ , c := range p .conns {
7789 err := c .Close ()
@@ -84,20 +96,29 @@ func (p *Pool) Close() error {
8496}
8597
8698func (p * Pool ) conn () (* Connection , error ) {
87- p .mu .RLock ()
88-
89- if p .closed {
90- p .mu .RUnlock ()
99+ if atomic .LoadInt32 (& p .closed ) == poolIsClosed {
91100 return nil , errPoolClosed
92101 }
93- p .mu .RUnlock ()
94102
95103 pos := atomic .AddInt32 (& p .pointer , 1 )
96104 if pos == int32 (len (p .conns )) {
97105 atomic .StoreInt32 (& p .pointer , 0 )
98106 }
99107 pos = pos % int32 (len (p .conns ))
100108
109+ if p .conns [pos ] == nil {
110+ p .mu .Lock ()
111+ defer p .mu .Unlock ()
112+
113+ if p .conns [pos ] == nil {
114+ var err error
115+ p .conns [pos ], err = NewConnection (p .host .String (), p .opts )
116+ if err != nil {
117+ return nil , err
118+ }
119+ }
120+ }
121+
101122 return p .conns [pos ], nil
102123}
103124
0 commit comments