From 1d665da32fa0d93af6aeba6cc302ea615b599aaf Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Fri, 22 Apr 2022 17:58:50 +0200 Subject: [PATCH] Prevent dangling cat-file calls (goroutine alternative) (#19454) (#19466) If an `os/exec.Command` is passed non `*os.File` as an input/output, go will create `os.Pipe`s and wait for their closure in `cmd.Wait()`. If the code following this is responsible for closing `io.Pipe`s or other handlers then on process death from context cancellation the `Wait` can hang. There are two possible solutions: 1. use `os.Pipe` as the input/output as `cmd.Wait` does not wait for these. 2. create a goroutine waiting on the context cancellation that will close the inputs. This PR provides the second option - which is a simpler change that can be more easily backported. Closes #19448 Signed-off-by: Andrew Thornton Co-authored-by: zeripath --- modules/git/batch_reader.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/git/batch_reader.go b/modules/git/batch_reader.go index 7f7272c19e..3b9d0f95c4 100644 --- a/modules/git/batch_reader.go +++ b/modules/git/batch_reader.go @@ -54,6 +54,12 @@ func CatFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError, <-closed } + // Ensure cancel is called as soon as the provided context is cancelled + go func() { + <-ctx.Done() + cancel() + }() + _, filename, line, _ := runtime.Caller(2) filename = strings.TrimPrefix(filename, callerPrefix) @@ -93,6 +99,12 @@ func CatFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufi <-closed } + // Ensure cancel is called as soon as the provided context is cancelled + go func() { + <-ctx.Done() + cancel() + }() + _, filename, line, _ := runtime.Caller(2) filename = strings.TrimPrefix(filename, callerPrefix)