Skip to content

Commit 18bb0ee

Browse files
committed
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 a7f0ce6 commit 18bb0ee

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

modules/git/batch_reader.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ func CatFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError,
5757
<-closed
5858
}
5959

60+
// Ensure cancel is called as soon as the provided context is cancelled
61+
go func() {
62+
<-ctx.Done()
63+
cancel()
64+
}()
65+
6066
_, filename, line, _ := runtime.Caller(2)
6167
filename = strings.TrimPrefix(filename, callerPrefix)
6268

@@ -101,6 +107,12 @@ func CatFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufi
101107
<-closed
102108
}
103109

110+
// Ensure cancel is called as soon as the provided context is cancelled
111+
go func() {
112+
<-ctx.Done()
113+
cancel()
114+
}()
115+
104116
_, filename, line, _ := runtime.Caller(2)
105117
filename = strings.TrimPrefix(filename, callerPrefix)
106118

0 commit comments

Comments
 (0)