diff options
| author | Junegunn Choi <junegunn.c@gmail.com> | 2024-11-03 15:14:35 +0900 |
|---|---|---|
| committer | Junegunn Choi <junegunn.c@gmail.com> | 2024-11-03 20:12:47 +0900 |
| commit | 19495eb9bbfa874647e7bc69e0fdff49d68b1dcf (patch) | |
| tree | feec000483143382c365d5d68dbce41860af9b4c /src/reader.go | |
| parent | bacc8609ee22fb9bbe34dc812ecb6075f4e58007 (diff) | |
| download | fzf-19495eb9bbfa874647e7bc69e0fdff49d68b1dcf.tar.gz | |
Remove possible races (#4070)
Diffstat (limited to 'src/reader.go')
| -rw-r--r-- | src/reader.go | 56 |
1 files changed, 24 insertions, 32 deletions
diff --git a/src/reader.go b/src/reader.go index 50e7809e..81782936 100644 --- a/src/reader.go +++ b/src/reader.go @@ -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) -} |
