forked from TrueCloudLab/restic
bloblru: fix race condition that can compute value multiple times
This commit is contained in:
parent
3828313974
commit
0ad0b7ca7c
1 changed files with 13 additions and 4 deletions
|
@ -114,10 +114,19 @@ func (c *Cache) GetOrCompute(id restic.ID, compute func() ([]byte, error)) ([]by
|
|||
if isDownloading {
|
||||
// wait for result of parallel download
|
||||
<-waitForResult
|
||||
blob, ok := c.Get(id)
|
||||
if ok {
|
||||
return blob, nil
|
||||
}
|
||||
}
|
||||
|
||||
// try again. This is necessary independent of whether isDownloading is true or not.
|
||||
// The calls to `c.Get()` and checking/adding the entry in `c.inProgress` are not atomic,
|
||||
// thus the item might have been computed in the meantime.
|
||||
// The following scenario would compute() the value multiple times otherwise:
|
||||
// Goroutine A does not find a value in the initial call to `c.Get`, then goroutine B
|
||||
// takes over, caches the computed value and cleans up its channel in c.inProgress.
|
||||
// Then goroutine A continues, does not detect a parallel computation and would try
|
||||
// to call compute() again.
|
||||
blob, ok = c.Get(id)
|
||||
if ok {
|
||||
return blob, nil
|
||||
}
|
||||
|
||||
// download it
|
||||
|
|
Loading…
Reference in a new issue