|
Fixes a potential TOCTOU issue that would cause values to be spuriously
erased.
IIUC, the following interleaving of (*DecayMap).Get() and
(*DecayMap).Set() can cause an update to be erased:
// thread A: Get("x")
m.lock.RLock()
value, ok := m.data["x"]
m.lock.RUnlock()
...
if time.Now().After(value.expiry) {
// <wait for lock!>
// thread B: Set("x", ...)
m.lock.Lock()
defer m.lock.Unlock()
m.data["x"] = DecayMapEntry{ ... }
// thread A continues its Get("x") after acquring the lock:
m.lock.Lock()
delete(m.data, "x") // Oops! Newer entry is deleted!
m.lock.Unlock()
Realistically... I think it's probably a non-issue either way, because
the worst that can happen is that a cache entry is spuriously removed,
and it'll just get re-fetched.
|