Fix a bug in OncePer.Get that could return a waiter

OncePer.Get must call maybeWaitFor on the value it reads, otherwise
it could return a waiter instead of the real value.

Test: onceper_test.go
Change-Id: I7d407bd1c577dbb43bc14fa107d5f606bf2b1c67
This commit is contained in:
Colin Cross 2019-02-15 23:00:48 -08:00
parent 4f41bc2bed
commit d7cfaeeebc
2 changed files with 32 additions and 1 deletions

View file

@ -70,7 +70,7 @@ func (once *OncePer) Get(key OnceKey) interface{} {
panic(fmt.Errorf("Get() called before Once()"))
}
return v
return once.maybeWaitFor(key, v)
}
// OnceStringSlice is the same as Once, but returns the value cast to a []string

View file

@ -16,6 +16,7 @@ package android
import (
"testing"
"time"
)
func TestOncePer_Once(t *testing.T) {
@ -34,6 +35,21 @@ func TestOncePer_Once(t *testing.T) {
}
}
func TestOncePer_Once_wait(t *testing.T) {
once := OncePer{}
key := NewOnceKey("key")
ch := make(chan bool)
go once.Once(key, func() interface{} { close(ch); time.Sleep(100 * time.Millisecond); return "foo" })
<-ch
a := once.Once(key, func() interface{} { return "bar" }).(string)
if a != "foo" {
t.Errorf("expect %q, got %q", "foo", a)
}
}
func TestOncePer_Get(t *testing.T) {
once := OncePer{}
key := NewOnceKey("key")
@ -65,6 +81,21 @@ func TestOncePer_Get_panic(t *testing.T) {
once.Get(key)
}
func TestOncePer_Get_wait(t *testing.T) {
once := OncePer{}
key := NewOnceKey("key")
ch := make(chan bool)
go once.Once(key, func() interface{} { close(ch); time.Sleep(100 * time.Millisecond); return "foo" })
<-ch
a := once.Get(key).(string)
if a != "foo" {
t.Errorf("expect %q, got %q", "foo", a)
}
}
func TestOncePer_OnceStringSlice(t *testing.T) {
once := OncePer{}
key := NewOnceKey("key")