fixes #460 Possible race condition between Fini and PollEvent

This commit is contained in:
Garrett D'Amore 2021-05-16 09:02:59 -07:00
parent 876e1fdeb5
commit 0bfa151864
2 changed files with 14 additions and 6 deletions

View File

@ -41,6 +41,7 @@ type cScreen struct {
fini bool
vten bool
truecolor bool
running bool
w int
h int
@ -267,12 +268,12 @@ func (s *cScreen) Fini() {
func (s *cScreen) disengage() {
s.Lock()
stopQ := s.stopQ
if stopQ == nil {
if !s.running {
s.Unlock()
return
}
s.stopQ = nil
s.running = false
stopQ := s.stopQ
procSetEvent.Call(uintptr(s.cancelflag))
close(stopQ)
s.Unlock()
@ -293,7 +294,7 @@ func (s *cScreen) disengage() {
func (s *cScreen) engage() error {
s.Lock()
defer s.Unlock()
if s.stopQ != nil {
if s.running {
return errors.New("already engaged")
}
s.stopQ = make(chan struct{})
@ -305,6 +306,7 @@ func (s *cScreen) engage() error {
if cf == uintptr(0) {
return e
}
s.running = true
s.cancelflag = syscall.Handle(cf)
s.enableMouse(s.mouseEnabled)

View File

@ -125,6 +125,7 @@ type tScreen struct {
disablePaste string
saved *term.State
stopQ chan struct{}
running bool
wg sync.WaitGroup
mouseFlags MouseFlags
pasteEnabled bool
@ -1601,12 +1602,13 @@ func (t *tScreen) engage() error {
if t.tty == nil {
return ErrNoScreen
}
if t.stopQ != nil {
if t.running {
return errors.New("already engaged")
}
if err := t.tty.Start(); err != nil {
return err
}
t.running = true
if w, h, err := t.tty.WindowSize(); err == nil && w != 0 && h != 0 {
t.cells.Resize(w, h)
}
@ -1635,8 +1637,12 @@ func (t *tScreen) engage() error {
func (t *tScreen) disengage() {
t.Lock()
if !t.running {
t.Unlock()
return
}
t.running = false
stopQ := t.stopQ
t.stopQ = nil
close(stopQ)
_ = t.tty.Drain()
t.Unlock()