From 3f18d5890e4f8acb7cd3a65579617b55e87951d2 Mon Sep 17 00:00:00 2001 From: Sean Young <sean.young@monax.io> Date: Fri, 6 Apr 2018 11:19:03 +0100 Subject: [PATCH] Fix locking issues in name cache Avoid concurrent duplicate calls to backend.GetNameEntry(). This avoids duplicate work but holds a write lock for the duration. Ensure we unlock in error path in Sync. Signed-off-by: Sean Young <sean.young@monax.io> --- execution/namereg_cache.go | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/execution/namereg_cache.go b/execution/namereg_cache.go index f941b9f9..5cb0c63a 100644 --- a/execution/namereg_cache.go +++ b/execution/namereg_cache.go @@ -109,11 +109,13 @@ func (cache *NameRegCache) Sync(state NameRegWriter) error { if nameInfo.removed { err := state.RemoveNameRegEntry(name) if err != nil { + nameInfo.RUnlock() return err } } else if nameInfo.updated { err := state.UpdateNameRegEntry(nameInfo.entry) if err != nil { + nameInfo.RUnlock() return err } } @@ -150,16 +152,19 @@ func (cache *NameRegCache) get(name string) (*nameInfo, error) { nmeInfo := cache.names[name] cache.RUnlock() if nmeInfo == nil { - entry, err := cache.backend.GetNameRegEntry(name) - if err != nil { - return nil, err - } - nmeInfo = &nameInfo{ - entry: entry, - } cache.Lock() - cache.names[name] = nmeInfo - cache.Unlock() + defer cache.Unlock() + nmeInfo = cache.names[name] + if nmeInfo == nil { + entry, err := cache.backend.GetNameRegEntry(name) + if err != nil { + return nil, err + } + nmeInfo = &nameInfo{ + entry: entry, + } + cache.names[name] = nmeInfo + } } return nmeInfo, nil } -- GitLab