Skip to content

Commit

Permalink
Make cancel from CatFileBatch and CatFileBatchCheck wait for the comm…
Browse files Browse the repository at this point in the history
…and to end (#16479) (#16480)

* 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 <art27@cantab.net>
  • Loading branch information
zeripath authored Jul 20, 2021
1 parent d268c9d commit 0c3467f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 2 deletions.
15 changes: 13 additions & 2 deletions modules/git/batch_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package git
import (
"bufio"
"bytes"
"context"
"io"
"math"
"strconv"
Expand All @@ -28,23 +29,28 @@ type WriteCloserError interface {
func CatFileBatchCheck(repoPath string) (WriteCloserError, *bufio.Reader, func()) {
batchStdinReader, batchStdinWriter := io.Pipe()
batchStdoutReader, batchStdoutWriter := io.Pipe()
ctx, ctxCancel := context.WithCancel(DefaultContext)
closed := make(chan struct{})
cancel := func() {
_ = batchStdinReader.Close()
_ = batchStdinWriter.Close()
_ = batchStdoutReader.Close()
_ = batchStdoutWriter.Close()
ctxCancel()
<-closed
}

go func() {
stderr := strings.Builder{}
err := NewCommand("cat-file", "--batch-check").RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
err := NewCommandContext(ctx, "cat-file", "--batch-check").RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
if err != nil {
_ = batchStdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String()))
_ = batchStdinReader.CloseWithError(ConcatenateError(err, (&stderr).String()))
} else {
_ = batchStdoutWriter.Close()
_ = batchStdinReader.Close()
}
close(closed)
}()

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

go func() {
stderr := strings.Builder{}
err := NewCommand("cat-file", "--batch").RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
err := NewCommandContext(ctx, "cat-file", "--batch").RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
if err != nil {
_ = batchStdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String()))
_ = batchStdinReader.CloseWithError(ConcatenateError(err, (&stderr).String()))
} else {
_ = batchStdoutWriter.Close()
_ = batchStdinReader.Close()
}
close(closed)
}()

// For simplicities sake we'll us a buffered reader to read from the cat-file --batch
Expand Down
21 changes: 21 additions & 0 deletions modules/util/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ package util

import (
"os"
"runtime"
"syscall"
"time"
)

const windowsSharingViolationError syscall.Errno = 32

// Remove removes the named file or (empty) directory with at most 5 attempts.
func Remove(name string) error {
var err error
Expand All @@ -25,6 +28,12 @@ func Remove(name string) error {
continue
}

if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" {
// try again
<-time.After(100 * time.Millisecond)
continue
}

if unwrapped == syscall.ENOENT {
// it's already gone
return nil
Expand All @@ -48,6 +57,12 @@ func RemoveAll(name string) error {
continue
}

if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" {
// try again
<-time.After(100 * time.Millisecond)
continue
}

if unwrapped == syscall.ENOENT {
// it's already gone
return nil
Expand All @@ -71,6 +86,12 @@ func Rename(oldpath, newpath string) error {
continue
}

if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" {
// try again
<-time.After(100 * time.Millisecond)
continue
}

if i == 0 && os.IsNotExist(err) {
return err
}
Expand Down

0 comments on commit 0c3467f

Please sign in to comment.