internal/memoize: fix race on read of handle.function

Late into CL 206879 I started nulling out a handle's function when the
handle finished running. That invalidated a previous assumption that the
field was immutable. Fix the assumption, and since the case of having
multiple computations in flight is at least a little bit possible, try
harder to avoid duplicate work.

Fixes golang/go#35995.

Change-Id: Ib5e3640f931f95e35748f28f5a82cf75585b305d
Reviewed-on: https://go-review.googlesource.com/c/tools/+/210077
Run-TryBot: Heschi Kreinick <heschi@google.com>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Heschi Kreinick 2019-12-05 13:24:16 -05:00
parent e140590b16
commit 61fa4dffed
1 changed files with 7 additions and 1 deletions

View File

@ -193,8 +193,14 @@ func (h *Handle) run(ctx context.Context) interface{} {
h.cancel = cancel
h.state = stateRunning
h.done = make(chan struct{})
function := h.function // Read under the lock
go func() {
v := h.function(childCtx)
// Just in case the function does something expensive without checking
// the context, double-check we're still alive.
if childCtx.Err() != nil {
return
}
v := function(childCtx)
if childCtx.Err() != nil {
return
}