From 073dae2be2878ac1d8113930579c6459cd4acc92 Mon Sep 17 00:00:00 2001 From: Lukas Braun <lukas.braun@fau.de> Date: Fri, 27 Jan 2017 21:13:03 +0100 Subject: [PATCH] comment on userlocks synchronization --- goatherd.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/goatherd.go b/goatherd.go index 29c9a2f..cc02fcc 100644 --- a/goatherd.go +++ b/goatherd.go @@ -259,14 +259,17 @@ func handle_conn(db *sql.DB, conn net.Conn) { } log.Printf("%v: %v", name, result) - // name exists, get or create its lock + // name exists, so we can get or create its lock, double-checked locking style + // NOTE: the read lock is important to synchronize with the mutex initiali- + // zation, not just the map itself (i.e. a reader might observe a non- + // zeroed mutex if we used a concurrent map without a temporary variable + // and further memory barriers) faildelay.RLock() delay, exists := faildelay.userlocks[name] faildelay.RUnlock() if !exists { debugf("[%v] not yet in faildelay.userlocks", remote) - // no atomic upgrade with sync.RWMutex, so we have to do the lookup again faildelay.Lock() delay, exists = faildelay.userlocks[name] if !exists { -- GitLab