If the callback passed to Once panics it was leaving the waiter
in place that would never be completed. Move writing the value
and signalling the waiter to defer.
Test: TestOncePerPanic
Change-Id: Icc4d3b779a79914fcd881d61d38dffcc2f591c39
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
The value constructor passed to OncePer.Once may call back into
Once. Replace the global mutex with a temporary channel stored
in the map using the key, and have callers for the same key
wait on the channel if they find it instead of a real value.
Test: TestOncePerReentrant
Change-Id: Ifa88a3c48981b5076b83f47fbdee5d26311725c6
Require that the key for Once calls be created with NewOnceKey
or NewCustomOnceKey.
Test: m checkbuild
Change-Id: I44b8ea6034338b45f558f862b21d5732364cbf0f
Add an opaque OnceKey type and use it for all calls to Once in
build/soong. A future patch will convert the arguments to
Once* to OnceKey once users outside build/soong have been updated.
Test: onceper_test.go
Change-Id: Ifcb338e6e603e804e507203c9508d30ffb2df966
Allow functions to get the result associated with a OncePer key without
also specifiying a function. Panics if the key has not already been
set. Also replace the open-coded concurrent map implementation with
the new sync.Map.
Test: m checkbuild
Change-Id: I814fdb1ffffaee8398dc877af146e29638c8a6a8
Add DeviceConfig to store per-device configuration information. Put a
OncePer object inside Config and DeviceConfig, which computes a value
once per key per object to allow build logic to store arbitrary
per-build or per-device computed values.
Change-Id: I1a38b426f29d223ef5e803e0d4d9604500de2fd2