Skip to content

Commit 0c61b04

Browse files
committed
fix: avoid wrong lock deletation
1 parent e4e6491 commit 0c61b04

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

control/dns_control.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"strconv"
1515
"strings"
1616
"sync"
17+
"sync/atomic"
1718
"time"
1819

1920
"github.com/daeuniverse/dae/common/consts"
@@ -82,6 +83,11 @@ type DnsController struct {
8283
dnsForwarderCache map[dnsForwarderKey]DnsForwarder
8384
}
8485

86+
type handlingState struct {
87+
mu sync.Mutex
88+
ref uint32
89+
}
90+
8591
func parseIpVersionPreference(prefer int) (uint16, error) {
8692
switch prefer := IpVersionPrefer(prefer); prefer {
8793
case IpVersionPrefer_No:
@@ -453,11 +459,17 @@ func (c *DnsController) handle_(
453459
}
454460

455461
// No parallel for the same lookup.
456-
_mu, _ := c.handling.LoadOrStore(cacheKey, new(sync.Mutex))
457-
mu := _mu.(*sync.Mutex)
458-
mu.Lock()
459-
defer mu.Unlock()
460-
defer c.handling.Delete(cacheKey)
462+
handlingState_, _ := c.handling.LoadOrStore(cacheKey, new(handlingState))
463+
handlingState := handlingState_.(*handlingState)
464+
atomic.AddUint32(&handlingState.ref, 1)
465+
handlingState.mu.Lock()
466+
defer func() {
467+
handlingState.mu.Unlock()
468+
atomic.AddUint32(&handlingState.ref, ^uint32(0))
469+
if atomic.LoadUint32(&handlingState.ref) == 0 {
470+
c.handling.Delete(cacheKey)
471+
}
472+
}()
461473

462474
if resp := c.LookupDnsRespCache_(dnsMessage, cacheKey, false); resp != nil {
463475
// Send cache to client directly.

0 commit comments

Comments
 (0)