Skip to content

Commit

Permalink
Prevent dangling cat-file calls (goroutine alternative) (go-gitea#19454)
Browse files Browse the repository at this point in the history
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 <art27@cantab.net>
  • Loading branch information
zeripath authored and AbdulrhmnGhanem committed Aug 23, 2022
1 parent 31a26da commit 66dc2f9
Showing 1 changed file with 12 additions and 0 deletions.
12 changes: 12 additions & 0 deletions modules/git/batch_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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)

Expand Down

0 comments on commit 66dc2f9

Please sign in to comment.