m/fzf
1
0
mirror of https://github.com/junegunn/fzf.git synced 2025-11-18 00:03:39 -05:00

Remove possible races (#4070)

This commit is contained in:
Junegunn Choi
2024-11-03 15:14:35 +09:00
parent bacc8609ee
commit 19495eb9bb
3 changed files with 39 additions and 39 deletions

View File

@@ -6,7 +6,6 @@ import (
"io"
"io/fs"
"os"
"os/exec"
"path/filepath"
"sync"
"sync/atomic"
@@ -98,20 +97,14 @@ func (r *Reader) terminate() {
r.mutex.Unlock()
}
func (r *Reader) restart(command commandSpec, environ []string) {
func (r *Reader) restart(command commandSpec, environ []string, readyChan chan bool) {
r.event = int32(EvtReady)
r.startEventPoller()
r.mutex.Lock()
defer r.mutex.Unlock()
if exec, execOut := r.startCommand(command.command, environ); exec != nil {
go func() {
success := r.feedCommandOutput(exec, execOut)
r.fin(success)
removeFiles(command.tempFiles)
}()
}
success := r.readFromCommand(command.command, environ, func() {
readyChan <- true
})
r.fin(success)
removeFiles(command.tempFiles)
}
func (r *Reader) readChannel(inputChan chan string) bool {
@@ -128,21 +121,29 @@ func (r *Reader) readChannel(inputChan chan string) bool {
}
// ReadSource reads data from the default command or from standard input
func (r *Reader) ReadSource(inputChan chan string, root string, opts walkerOpts, ignores []string, initCmd string, initEnv []string) {
func (r *Reader) ReadSource(inputChan chan string, root string, opts walkerOpts, ignores []string, initCmd string, initEnv []string, readyChan chan bool) {
r.startEventPoller()
var success bool
signalReady := func() {
if readyChan != nil {
readyChan <- true
}
}
if inputChan != nil {
signalReady()
success = r.readChannel(inputChan)
} else if len(initCmd) > 0 {
success = r.readFromCommand(initCmd, initEnv)
success = r.readFromCommand(initCmd, initEnv, signalReady)
} else if util.IsTty(os.Stdin) {
cmd := os.Getenv("FZF_DEFAULT_COMMAND")
if len(cmd) == 0 {
signalReady()
success = r.readFiles(root, opts, ignores)
} else {
success = r.readFromCommand(cmd, initEnv)
success = r.readFromCommand(cmd, initEnv, signalReady)
}
} else {
signalReady()
success = r.readFromStdin()
}
r.fin(success)
@@ -304,8 +305,9 @@ func (r *Reader) readFiles(root string, opts walkerOpts, ignores []string) bool
return fastwalk.Walk(&conf, root, fn) == nil
}
// Should be called with the mutex held
func (r *Reader) startCommand(command string, environ []string) (*exec.Cmd, io.ReadCloser) {
func (r *Reader) readFromCommand(command string, environ []string, signalReady func()) bool {
r.mutex.Lock()
r.termFunc = nil
r.command = &command
exec := r.executor.ExecCommand(command, true)
@@ -314,7 +316,8 @@ func (r *Reader) startCommand(command string, environ []string) (*exec.Cmd, io.R
}
execOut, err := exec.StdoutPipe()
if err != nil || exec.Start() != nil {
return nil, nil
r.mutex.Unlock()
return false
}
// Function to call to terminate the running command
@@ -323,20 +326,9 @@ func (r *Reader) startCommand(command string, environ []string) (*exec.Cmd, io.R
util.KillCommand(exec)
}
return exec, execOut
}
signalReady()
r.mutex.Unlock()
func (r *Reader) feedCommandOutput(exec *exec.Cmd, execOut io.ReadCloser) bool {
r.feed(execOut)
return exec.Wait() == nil
}
func (r *Reader) readFromCommand(command string, environ []string) bool {
r.mutex.Lock()
exec, execOut := r.startCommand(command, environ)
r.mutex.Unlock()
if exec == nil {
return false
}
return r.feedCommandOutput(exec, execOut)
}