siso: fix crash in lazyCompute: "send no closed channel".

When interrupted, build finished and hashfs is closed,
but some goroutines for scandeps keep running, and
it would trigger lazyCompute and try to send on closed channel.

Set digester's q to nil when closed,
and check it in lazyCompute before sending to the channel.

Also check whether ctx is done in lazyCompute and compute.

Bug: b/347635033
Change-Id: I5ef43467264b8621aebb12936773f93a9d6f65ef
Reviewed-on: https://chromium-review.googlesource.com/c/infra/infra/+/5636173
Reviewed-by: Takuto Ikuta <tikuta@chromium.org>
Auto-Submit: Fumitoshi Ukai <ukai@google.com>
Commit-Queue: Fumitoshi Ukai <ukai@google.com>
Cr-Commit-Position: refs/heads/main@{#66253}
diff --git a/go/src/infra/build/siso/hashfs/digester.go b/go/src/infra/build/siso/hashfs/digester.go
index 72d13a6..6af3436 100644
--- a/go/src/infra/build/siso/hashfs/digester.go
+++ b/go/src/infra/build/siso/hashfs/digester.go
@@ -112,9 +112,13 @@
 	close(d.quit)
 	clog.Infof(ctx, "wait for workers")
 	<-d.done
-	close(d.q)
+	d.mu.Lock()
+	q := d.q
+	d.q = nil
+	d.mu.Unlock()
+	close(q)
 	clog.Infof(ctx, "run pending digest chan:%d + queue:%d", len(d.q), len(d.queue))
-	for req := range d.q {
+	for req := range q {
 		d.compute(req.ctx, req.fname, req.e)
 	}
 	for _, req := range d.queue {
@@ -125,6 +129,12 @@
 }
 
 func (d *digester) lazyCompute(ctx context.Context, fname string, e *entry) {
+	select {
+	case <-ctx.Done():
+		clog.Warningf(ctx, "ignore lazyCompute %s: %v", fname, context.Cause(ctx))
+		return
+	default:
+	}
 	req := digestReq{
 		ctx:   ctx,
 		fname: fname,
@@ -132,6 +142,9 @@
 	}
 	d.mu.Lock()
 	defer d.mu.Unlock()
+	if d.q == nil {
+		return
+	}
 	select {
 	case d.q <- req:
 	default:
@@ -144,6 +157,12 @@
 		return
 	}
 	err := DigestSemaphore.Do(ctx, func(ctx context.Context) error {
+		select {
+		case <-ctx.Done():
+			clog.Warningf(ctx, "ignore compute %s: %v", fname, context.Cause(ctx))
+			return context.Cause(ctx)
+		default:
+		}
 		return e.compute(ctx, fname)
 	})
 	if err != nil {