@@ -12,16 +12,26 @@ const (
1212 stateClosed = 2
1313)
1414
15- var ErrBadConn = fmt .Errorf ("pg: Conn is in a bad state" )
15+ type BadConnError struct {
16+ wrapped error
17+ }
18+
19+ func (e BadConnError ) Error () string {
20+ return "pg: Conn is in a bad state"
21+ }
22+
23+ func (e BadConnError ) Unwrap () error {
24+ return e .wrapped
25+ }
1626
1727type SingleConnPool struct {
1828 pool Pooler
1929
2030 state uint32 // atomic
2131 ch chan * Conn
2232
23- level int32 // atomic
24- _hasBadConn uint32 // atomic
33+ level int32 // atomic
34+ _badConnError atomic. Value
2535}
2636
2737var _ Pooler = (* SingleConnPool )(nil )
@@ -66,10 +76,10 @@ func (p *SingleConnPool) Get(c context.Context) (*Conn, error) {
6676 if atomic .CompareAndSwapUint32 (& p .state , stateDefault , stateInited ) {
6777 return cn , nil
6878 }
69- p .pool .Remove (cn )
79+ p .pool .Remove (cn , ErrClosed )
7080 case stateInited :
71- if p . hasBadConn () {
72- return nil , ErrBadConn
81+ if err := p . badConnError (); err != nil {
82+ return nil , err
7383 }
7484 cn , ok := <- p .ch
7585 if ! ok {
@@ -95,20 +105,20 @@ func (p *SingleConnPool) Put(cn *Conn) {
95105}
96106
97107func (p * SingleConnPool ) freeConn (cn * Conn ) {
98- if p . hasBadConn () {
99- p .pool .Remove (cn )
108+ if err := p . badConnError (); err != nil {
109+ p .pool .Remove (cn , err )
100110 } else {
101111 p .pool .Put (cn )
102112 }
103113}
104114
105- func (p * SingleConnPool ) Remove (cn * Conn ) {
115+ func (p * SingleConnPool ) Remove (cn * Conn , reason error ) {
106116 defer func () {
107117 if recover () != nil {
108- p .pool .Remove (cn )
118+ p .pool .Remove (cn , ErrClosed )
109119 }
110120 }()
111- atomic . StoreUint32 ( & p . _hasBadConn , 1 )
121+ p . _badConnError . Store ( BadConnError { wrapped : reason } )
112122 p .ch <- cn
113123}
114124
@@ -158,7 +168,7 @@ func (p *SingleConnPool) Close() error {
158168}
159169
160170func (p * SingleConnPool ) Reset () error {
161- if ! atomic . CompareAndSwapUint32 ( & p . _hasBadConn , 1 , 0 ) {
171+ if p . badConnError () == nil {
162172 return nil
163173 }
164174
@@ -167,7 +177,8 @@ func (p *SingleConnPool) Reset() error {
167177 if ! ok {
168178 return ErrClosed
169179 }
170- p .pool .Remove (cn )
180+ p .pool .Remove (cn , ErrClosed )
181+ p ._badConnError .Store (nil )
171182 default :
172183 return fmt .Errorf ("pg: SingleConnPool does not have a Conn" )
173184 }
@@ -180,6 +191,9 @@ func (p *SingleConnPool) Reset() error {
180191 return nil
181192}
182193
183- func (p * SingleConnPool ) hasBadConn () bool {
184- return atomic .LoadUint32 (& p ._hasBadConn ) == 1
194+ func (p * SingleConnPool ) badConnError () error {
195+ if v := p ._badConnError .Load (); v != nil {
196+ return v .(BadConnError )
197+ }
198+ return nil
185199}
0 commit comments