Skip to content

Commit

Permalink
Fix crash caused by simultaneous read/write of scanner buffer (#2813)
Browse files Browse the repository at this point in the history
  • Loading branch information
jesseduffield committed Jul 23, 2023
2 parents 6f13b42 + 28474b0 commit 1b05ba2
Showing 1 changed file with 15 additions and 4 deletions.
19 changes: 15 additions & 4 deletions pkg/tasks/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,18 +164,27 @@ func (self *ViewBufferManager) NewCmdTask(start func() (*exec.Cmd, io.Reader), p
scanner := bufio.NewScanner(r)
scanner.Split(bufio.ScanLines)

data := make(chan []byte)
lineChan := make(chan []byte)
lineWrittenChan := make(chan struct{})

// We're reading from the scanner in a separate goroutine because on windows
// if running git through a shim, we sometimes kill the parent process without
// killing its children, meaning the scanner blocks forever. This solution
// leaves us with a dead goroutine, but it's better than blocking all
// rendering to main views.
go utils.Safe(func() {
defer close(lineChan)
for scanner.Scan() {
data <- scanner.Bytes()
select {
case <-opts.Stop:
return
case lineChan <- scanner.Bytes():
// We need to confirm the data has been fed into the view before we
// pull more from the scanner because the scanner uses the same backing
// array and we don't want to be mutating that while it's being written
<-lineWrittenChan
}
}
close(data)
})

loaded := false
Expand Down Expand Up @@ -222,7 +231,7 @@ func (self *ViewBufferManager) NewCmdTask(start func() (*exec.Cmd, io.Reader), p
select {
case <-opts.Stop:
break outer
case line, ok = <-data:
case line, ok = <-lineChan:
break
}

Expand All @@ -243,6 +252,7 @@ func (self *ViewBufferManager) NewCmdTask(start func() (*exec.Cmd, io.Reader), p
break outer
}
writeToView(append(line, '\n'))
lineWrittenChan <- struct{}{}

if i+1 == linesToRead.InitialRefreshAfter {
// We have read enough lines to fill the view, so do a first refresh
Expand All @@ -269,6 +279,7 @@ func (self *ViewBufferManager) NewCmdTask(start func() (*exec.Cmd, io.Reader), p
onDone()

close(done)
close(lineWrittenChan)
})

self.readLines <- linesToRead
Expand Down

0 comments on commit 1b05ba2

Please sign in to comment.