aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzeripath <art27@cantab.net>2022-04-22 16:20:04 +0100
committerGitHub <noreply@github.com>2022-04-22 17:20:04 +0200
commit0dcc74a8a7eebe816f855ad0375714c52f8b785a (patch)
tree3cf17d682ece3424a22079f4f7aae9b150308c3f
parent0dfc2e55ea258d2b1a3cd86e2b6f27a481e495ff (diff)
downloadgitea-0dcc74a8a7eebe816f855ad0375714c52f8b785a.tar.gz
gitea-0dcc74a8a7eebe816f855ad0375714c52f8b785a.zip
Prevent dangling cat-file calls (goroutine alternative) (#19454)
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 <art27@cantab.net>
-rw-r--r--modules/git/batch_reader.go12
1 files changed, 12 insertions, 0 deletions
diff --git a/modules/git/batch_reader.go b/modules/git/batch_reader.go
index 5a0a82b13a..902fa89718 100644
--- a/modules/git/batch_reader.go
+++ b/modules/git/batch_reader.go
@@ -57,6 +57,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)
@@ -101,6 +107,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)