Skip to content

Commit 957e241

Browse files
zeripath6543
authored andcommitted
Prevent dangling cat-file calls (goroutine alternative)
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 go-gitea#19448 Signed-off-by: Andrew Thornton <[email protected]>
1 parent 0e87746 commit 957e241

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

modules/git/batch_reader.go

+12
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ func CatFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError,
5454
<-closed
5555
}
5656

57+
// Ensure cancel is called as soon as the provided context is cancelled
58+
go func() {
59+
<-ctx.Done()
60+
cancel()
61+
}()
62+
5763
_, filename, line, _ := runtime.Caller(2)
5864
filename = strings.TrimPrefix(filename, callerPrefix)
5965

@@ -93,6 +99,12 @@ func CatFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufi
9399
<-closed
94100
}
95101

102+
// Ensure cancel is called as soon as the provided context is cancelled
103+
go func() {
104+
<-ctx.Done()
105+
cancel()
106+
}()
107+
96108
_, filename, line, _ := runtime.Caller(2)
97109
filename = strings.TrimPrefix(filename, callerPrefix)
98110

0 commit comments

Comments
 (0)