forked from Mirrors/bubbletea
fix: wait for read-loop to finish before spawning child process
This commit is contained in:
parent
93c63f07aa
commit
b1c9d80603
10
tea.go
10
tea.go
|
@ -292,13 +292,7 @@ func (p *Program) StartReturningModel() (Model, error) {
|
|||
|
||||
waitForGoroutines = func(withReadLoop bool) {
|
||||
if withReadLoop {
|
||||
select {
|
||||
case <-p.readLoopDone:
|
||||
case <-time.After(500 * time.Millisecond):
|
||||
// The read loop hangs, which means the input
|
||||
// cancelReader's cancel function has returned true even
|
||||
// though it was not able to cancel the read.
|
||||
}
|
||||
p.waitForReadLoop()
|
||||
}
|
||||
<-cmdLoopDone
|
||||
<-resizeLoopDone
|
||||
|
@ -712,6 +706,8 @@ func (p *Program) DisableMouseAllMotion() {
|
|||
func (p *Program) ReleaseTerminal() error {
|
||||
p.ignoreSignals = true
|
||||
p.cancelInput()
|
||||
p.waitForReadLoop()
|
||||
|
||||
p.altScreenWasActive = p.altScreenActive
|
||||
if p.altScreenActive {
|
||||
p.ExitAltScreen()
|
||||
|
|
58
tty.go
58
tty.go
|
@ -3,6 +3,7 @@ package tea
|
|||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/muesli/cancelreader"
|
||||
)
|
||||
|
@ -48,33 +49,46 @@ func (p *Program) initCancelReader() error {
|
|||
}
|
||||
|
||||
p.readLoopDone = make(chan struct{})
|
||||
go func() {
|
||||
defer close(p.readLoopDone)
|
||||
|
||||
for {
|
||||
if p.ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
|
||||
msgs, err := readInputs(p.cancelReader)
|
||||
if err != nil {
|
||||
if !errors.Is(err, io.EOF) && !errors.Is(err, cancelreader.ErrCanceled) {
|
||||
p.errs <- err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
for _, msg := range msgs {
|
||||
p.msgs <- msg
|
||||
}
|
||||
}
|
||||
}()
|
||||
go p.eventLoop()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Program) eventLoop() {
|
||||
defer close(p.readLoopDone)
|
||||
|
||||
for {
|
||||
if p.ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
|
||||
msgs, err := readInputs(p.cancelReader)
|
||||
if err != nil {
|
||||
if !errors.Is(err, io.EOF) && !errors.Is(err, cancelreader.ErrCanceled) {
|
||||
p.errs <- err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
for _, msg := range msgs {
|
||||
p.msgs <- msg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cancelInput cancels the input reader.
|
||||
func (p *Program) cancelInput() {
|
||||
p.cancelReader.Cancel()
|
||||
}
|
||||
|
||||
// waitForReadLoop waits for the cancelReader to finish its read loop.
|
||||
func (p *Program) waitForReadLoop() {
|
||||
select {
|
||||
case <-p.readLoopDone:
|
||||
case <-time.After(500 * time.Millisecond):
|
||||
// The read loop hangs, which means the input
|
||||
// cancelReader's cancel function has returned true even
|
||||
// though it was not able to cancel the read.
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue