Skip to content

Commit 97381aa

Browse files
zeripathlafriks
andauthored
Make cancel from CatFileBatch and CatFileBatchCheck wait for the command to end (#16479)
Fix #16427 (again!) * handle sharing violation error code Signed-off-by: Andrew Thornton <[email protected]> Co-authored-by: Lauris BH <[email protected]>
1 parent b26c3b4 commit 97381aa

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

modules/git/batch_reader.go

+13-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package git
77
import (
88
"bufio"
99
"bytes"
10+
"context"
1011
"io"
1112
"math"
1213
"strconv"
@@ -28,23 +29,28 @@ type WriteCloserError interface {
2829
func CatFileBatchCheck(repoPath string) (WriteCloserError, *bufio.Reader, func()) {
2930
batchStdinReader, batchStdinWriter := io.Pipe()
3031
batchStdoutReader, batchStdoutWriter := io.Pipe()
32+
ctx, ctxCancel := context.WithCancel(DefaultContext)
33+
closed := make(chan struct{})
3134
cancel := func() {
3235
_ = batchStdinReader.Close()
3336
_ = batchStdinWriter.Close()
3437
_ = batchStdoutReader.Close()
3538
_ = batchStdoutWriter.Close()
39+
ctxCancel()
40+
<-closed
3641
}
3742

3843
go func() {
3944
stderr := strings.Builder{}
40-
err := NewCommand("cat-file", "--batch-check").RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
45+
err := NewCommandContext(ctx, "cat-file", "--batch-check").RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
4146
if err != nil {
4247
_ = batchStdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String()))
4348
_ = batchStdinReader.CloseWithError(ConcatenateError(err, (&stderr).String()))
4449
} else {
4550
_ = batchStdoutWriter.Close()
4651
_ = batchStdinReader.Close()
4752
}
53+
close(closed)
4854
}()
4955

5056
// For simplicities sake we'll use a buffered reader to read from the cat-file --batch-check
@@ -59,23 +65,28 @@ func CatFileBatch(repoPath string) (WriteCloserError, *bufio.Reader, func()) {
5965
// so let's create a batch stdin and stdout
6066
batchStdinReader, batchStdinWriter := io.Pipe()
6167
batchStdoutReader, batchStdoutWriter := nio.Pipe(buffer.New(32 * 1024))
68+
ctx, ctxCancel := context.WithCancel(DefaultContext)
69+
closed := make(chan struct{})
6270
cancel := func() {
6371
_ = batchStdinReader.Close()
6472
_ = batchStdinWriter.Close()
6573
_ = batchStdoutReader.Close()
6674
_ = batchStdoutWriter.Close()
75+
ctxCancel()
76+
<-closed
6777
}
6878

6979
go func() {
7080
stderr := strings.Builder{}
71-
err := NewCommand("cat-file", "--batch").RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
81+
err := NewCommandContext(ctx, "cat-file", "--batch").RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
7282
if err != nil {
7383
_ = batchStdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String()))
7484
_ = batchStdinReader.CloseWithError(ConcatenateError(err, (&stderr).String()))
7585
} else {
7686
_ = batchStdoutWriter.Close()
7787
_ = batchStdinReader.Close()
7888
}
89+
close(closed)
7990
}()
8091

8192
// For simplicities sake we'll us a buffered reader to read from the cat-file --batch

modules/util/remove.go

+21
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@ package util
66

77
import (
88
"os"
9+
"runtime"
910
"syscall"
1011
"time"
1112
)
1213

14+
const windowsSharingViolationError syscall.Errno = 32
15+
1316
// Remove removes the named file or (empty) directory with at most 5 attempts.
1417
func Remove(name string) error {
1518
var err error
@@ -25,6 +28,12 @@ func Remove(name string) error {
2528
continue
2629
}
2730

31+
if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" {
32+
// try again
33+
<-time.After(100 * time.Millisecond)
34+
continue
35+
}
36+
2837
if unwrapped == syscall.ENOENT {
2938
// it's already gone
3039
return nil
@@ -48,6 +57,12 @@ func RemoveAll(name string) error {
4857
continue
4958
}
5059

60+
if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" {
61+
// try again
62+
<-time.After(100 * time.Millisecond)
63+
continue
64+
}
65+
5166
if unwrapped == syscall.ENOENT {
5267
// it's already gone
5368
return nil
@@ -71,6 +86,12 @@ func Rename(oldpath, newpath string) error {
7186
continue
7287
}
7388

89+
if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" {
90+
// try again
91+
<-time.After(100 * time.Millisecond)
92+
continue
93+
}
94+
7495
if i == 0 && os.IsNotExist(err) {
7596
return err
7697
}

0 commit comments

Comments
 (0)