use new lock

This commit is contained in:
aliamerj
2025-09-18 12:41:09 +03:00
parent 3027029f7b
commit 2eba4af5ba
+32 -18
View File
@@ -14,7 +14,6 @@ import (
"sort" "sort"
"strings" "strings"
"sync" "sync"
"sync/atomic"
"time" "time"
"github.com/hashicorp/go-multierror" "github.com/hashicorp/go-multierror"
@@ -199,9 +198,10 @@ type Engine struct {
stateManager *statemanager.Manager stateManager *statemanager.Manager
srWatcher *guard.SRWatcher srWatcher *guard.SRWatcher
// Sync response persistence // Sync response persistence (protected by syncRespMux)
persistSyncResponse atomic.Bool syncRespMux sync.RWMutex
latestSyncResponse atomic.Pointer[mgmProto.SyncResponse] persistSyncResponse bool
latestSyncResponse *mgmProto.SyncResponse
connSemaphore *semaphoregroup.SemaphoreGroup connSemaphore *semaphoregroup.SemaphoreGroup
flowManager nftypes.FlowManager flowManager nftypes.FlowManager
@@ -662,8 +662,10 @@ func (e *Engine) removePeer(peerKey string) error {
return nil return nil
} }
// 1. xyzzz
func (e *Engine) handleSync(update *mgmProto.SyncResponse) error { func (e *Engine) handleSync(update *mgmProto.SyncResponse) error {
e.syncMsgMux.Lock()
defer e.syncMsgMux.Unlock()
if update.GetNetbirdConfig() != nil { if update.GetNetbirdConfig() != nil {
wCfg := update.GetNetbirdConfig() wCfg := update.GetNetbirdConfig()
err := e.updateTURNs(wCfg.GetTurns()) err := e.updateTURNs(wCfg.GetTurns())
@@ -702,11 +704,19 @@ func (e *Engine) handleSync(update *mgmProto.SyncResponse) error {
if nm == nil { if nm == nil {
return nil return nil
} }
persistSyncResponse := e.persistSyncResponse.Load()
// Persist sync response under the dedicated lock (syncRespMux), not under syncMsgMux.
// Read the storage-enabled flag under the syncRespMux too.
e.syncRespMux.RLock()
enabled := e.persistSyncResponse
e.syncRespMux.RUnlock()
// Store sync response if persistence is enabled // Store sync response if persistence is enabled
if persistSyncResponse { if enabled {
e.latestSyncResponse.Store(update) e.syncRespMux.Lock()
e.latestSyncResponse = update
e.syncRespMux.Unlock()
log.Debugf("sync response persisted with serial %d", nm.GetSerial()) log.Debugf("sync response persisted with serial %d", nm.GetSerial())
} }
@@ -1816,34 +1826,38 @@ func (e *Engine) stopDNSServer() {
// SetSyncResponsePersistence enables or disables sync response persistence // SetSyncResponsePersistence enables or disables sync response persistence
func (e *Engine) SetSyncResponsePersistence(enabled bool) { func (e *Engine) SetSyncResponsePersistence(enabled bool) {
persistSyncResponse := e.persistSyncResponse.Load() e.syncRespMux.Lock()
if enabled == persistSyncResponse { defer e.syncRespMux.Unlock()
if enabled == e.persistSyncResponse {
return return
} }
e.persistSyncResponse.Store(enabled) e.persistSyncResponse = enabled
log.Debugf("Sync response persistence is set to %t", enabled) log.Debugf("Sync response persistence is set to %t", enabled)
if !enabled { if !enabled {
e.latestSyncResponse.Store(nil) e.latestSyncResponse = nil
} }
} }
// GetLatestSyncResponse returns the stored sync response if persistence is enabled // GetLatestSyncResponse returns the stored sync response if persistence is enabled
func (e *Engine) GetLatestSyncResponse() (*mgmProto.SyncResponse, error) { func (e *Engine) GetLatestSyncResponse() (*mgmProto.SyncResponse, error) {
persistSyncResponse := e.persistSyncResponse.Load() e.syncRespMux.RLock()
enabled := e.persistSyncResponse
latest := e.latestSyncResponse
e.syncRespMux.RUnlock()
if !persistSyncResponse { if !enabled {
return nil, errors.New("sync response persistence is disabled") return nil, errors.New("sync response persistence is disabled")
} }
latestSyncResponse := e.latestSyncResponse.Load() if latest == nil {
if latestSyncResponse == nil {
//nolint:nilnil //nolint:nilnil
return nil, nil return nil, nil
} }
log.Debugf("Retrieving latest sync response with size %d bytes", proto.Size(latestSyncResponse)) log.Debugf("Retrieving latest sync response with size %d bytes", proto.Size(latest))
sr, ok := proto.Clone(latestSyncResponse).(*mgmProto.SyncResponse) sr, ok := proto.Clone(latest).(*mgmProto.SyncResponse)
if !ok { if !ok {
return nil, fmt.Errorf("failed to clone sync response") return nil, fmt.Errorf("failed to clone sync response")
} }