@@ -152,6 +152,7 @@ type clientConn struct {
152
152
lastActive time.Time // last active time
153
153
authPlugin string // default authentication plugin
154
154
isUnixSocket bool // connection is Unix Socket file
155
+ closeOnce sync.Once // closeOnce is used to make sure clientConn closes only once
155
156
rsEncoder * resultEncoder // rsEncoder is used to encode the string result to different charsets.
156
157
inputDecoder * inputDecoder // inputDecoder is used to decode the different charsets of incoming strings to utf-8.
157
158
socketCredUID uint32 // UID from the other end of the Unix Socket
@@ -320,21 +321,33 @@ func (cc *clientConn) Close() error {
320
321
}
321
322
322
323
func closeConn (cc * clientConn , connections int ) error {
323
- metrics .ConnGauge .Set (float64 (connections ))
324
- if cc .bufReadConn != nil {
325
- err := cc .bufReadConn .Close ()
326
- if err != nil {
327
- // We need to expect connection might have already disconnected.
328
- // This is because closeConn() might be called after a connection read-timeout.
329
- logutil .Logger (context .Background ()).Debug ("could not close connection" , zap .Error (err ))
324
+ var err error
325
+ cc .closeOnce .Do (func () {
326
+ metrics .ConnGauge .Set (float64 (connections ))
327
+
328
+ if cc .bufReadConn != nil {
329
+ err = cc .bufReadConn .Close ()
330
+ if err != nil {
331
+ // We need to expect connection might have already disconnected.
332
+ // This is because closeConn() might be called after a connection read-timeout.
333
+ logutil .Logger (context .Background ()).Debug ("could not close connection" , zap .Error (err ))
334
+ }
335
+ if cc .bufReadConn != nil {
336
+ err = cc .bufReadConn .Close ()
337
+ if err != nil {
338
+ // We need to expect connection might have already disconnected.
339
+ // This is because closeConn() might be called after a connection read-timeout.
340
+ logutil .Logger (context .Background ()).Debug ("could not close connection" , zap .Error (err ))
341
+ }
342
+ }
343
+ // Close statements and session
344
+ // This will release advisory locks, row locks, etc.
345
+ if ctx := cc .getCtx (); ctx != nil {
346
+ err = ctx .Close ()
347
+ }
330
348
}
331
- }
332
- // Close statements and session
333
- // This will release advisory locks, row locks, etc.
334
- if ctx := cc .getCtx (); ctx != nil {
335
- return ctx .Close ()
336
- }
337
- return nil
349
+ })
350
+ return err
338
351
}
339
352
340
353
func (cc * clientConn ) closeWithoutLock () error {
0 commit comments