X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/d0f91b34eedec9af266ec4877a3005dd627ad38e..e20590d485505f58f7745d74a311ca539c9be940:/services/keepstore/collision.go diff --git a/services/keepstore/collision.go b/services/keepstore/collision.go index a4af563729..16f2d09232 100644 --- a/services/keepstore/collision.go +++ b/services/keepstore/collision.go @@ -1,7 +1,12 @@ -package main +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +package keepstore import ( "bytes" + "context" "crypto/md5" "fmt" "io" @@ -49,7 +54,7 @@ func collisionOrCorrupt(expectMD5 string, buf1, buf2 []byte, rdr io.Reader) erro return <-outcome } -func compareReaderWithBuf(rdr io.Reader, expect []byte, hash string) error { +func compareReaderWithBuf(ctx context.Context, rdr io.Reader, expect []byte, hash string) error { bufLen := 1 << 20 if bufLen > len(expect) && len(expect) > 0 { // No need for bufLen to be longer than @@ -67,7 +72,18 @@ func compareReaderWithBuf(rdr io.Reader, expect []byte, hash string) error { // expected to equal the next N bytes read from // rdr. for { - n, err := rdr.Read(buf) + ready := make(chan bool) + var n int + var err error + go func() { + n, err = rdr.Read(buf) + close(ready) + }() + select { + case <-ready: + case <-ctx.Done(): + return ctx.Err() + } if n > len(cmp) || bytes.Compare(cmp[:n], buf[:n]) != 0 { return collisionOrCorrupt(hash, expect[:len(expect)-len(cmp)], buf[:n], rdr) }