@@ -207,6 +207,7 @@ type clientConn struct {
207
207
lastActive time.Time // last active time
208
208
authPlugin string // default authentication plugin
209
209
isUnixSocket bool // connection is Unix Socket file
210
+ closeOnce sync.Once // closeOnce is used to make sure clientConn closes only once
210
211
rsEncoder * resultEncoder // rsEncoder is used to encode the string result to different charsets.
211
212
inputDecoder * inputDecoder // inputDecoder is used to decode the different charsets of incoming strings to utf-8.
212
213
socketCredUID uint32 // UID from the other end of the Unix Socket
@@ -346,21 +347,33 @@ func (cc *clientConn) Close() error {
346
347
}
347
348
348
349
func closeConn (cc * clientConn , connections int ) error {
349
- metrics .ConnGauge .Set (float64 (connections ))
350
- if cc .bufReadConn != nil {
351
- err := cc .bufReadConn .Close ()
352
- if err != nil {
353
- // We need to expect connection might have already disconnected.
354
- // This is because closeConn() might be called after a connection read-timeout.
355
- logutil .Logger (context .Background ()).Debug ("could not close connection" , zap .Error (err ))
350
+ var err error
351
+ cc .closeOnce .Do (func () {
352
+ metrics .ConnGauge .Set (float64 (connections ))
353
+
354
+ if cc .bufReadConn != nil {
355
+ err = cc .bufReadConn .Close ()
356
+ if err != nil {
357
+ // We need to expect connection might have already disconnected.
358
+ // This is because closeConn() might be called after a connection read-timeout.
359
+ logutil .Logger (context .Background ()).Debug ("could not close connection" , zap .Error (err ))
360
+ }
361
+ if cc .bufReadConn != nil {
362
+ err = cc .bufReadConn .Close ()
363
+ if err != nil {
364
+ // We need to expect connection might have already disconnected.
365
+ // This is because closeConn() might be called after a connection read-timeout.
366
+ logutil .Logger (context .Background ()).Debug ("could not close connection" , zap .Error (err ))
367
+ }
368
+ }
369
+ // Close statements and session
370
+ // This will release advisory locks, row locks, etc.
371
+ if ctx := cc .getCtx (); ctx != nil {
372
+ err = ctx .Close ()
373
+ }
356
374
}
357
- }
358
- // Close statements and session
359
- // This will release advisory locks, row locks, etc.
360
- if ctx := cc .getCtx (); ctx != nil {
361
- return ctx .Close ()
362
- }
363
- return nil
375
+ })
376
+ return err
364
377
}
365
378
366
379
func (cc * clientConn ) closeWithoutLock () error {
0 commit comments