From 0bfa151864d6e772558e4033084c937ca51c8f0e Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Sun, 16 May 2021 09:02:59 -0700 Subject: [PATCH] fixes #460 Possible race condition between Fini and PollEvent --- console_win.go | 10 ++++++---- tscreen.go | 10 ++++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/console_win.go b/console_win.go index d1341cf1..227e4fcb 100644 --- a/console_win.go +++ b/console_win.go @@ -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) diff --git a/tscreen.go b/tscreen.go index 4e3b1c07..a0ffd701 100644 --- a/tscreen.go +++ b/tscreen.go @@ -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()