terminal: fix race when closing a terminal

Fix race when closing a terminal. The race appears as a nil pointer
dereference panic in pty.StartWithAttrs when trying to access the
provided term.cmd variable.

Before calling pty.StartwithAttrs in the Terminal.Draw function,
term.cmd is checked for nil. Terminal.Close must be called concurrently
right after this check and before/while entering pty.StartWithAttrs.
This can be avoided with a mutex.

Link: https://github.com/creack/pty/issues/146
Link: https://lists.sr.ht/~rjarry/aerc-devel/%3CCJ2I45HMOTGD.2J1QMEJ4T1E3N%40t450.arielp.com%3E#%3CCJ3D069RCTXL.3VEZ7JIGFHOHK@Archetype%3E
Fixes: https://todo.sr.ht/~rjarry/aerc/38
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
Koni Marti 2022-05-23 22:16:13 +02:00 committed by Robin Jarry
parent f4d4e2b4e1
commit 1bac87e804
1 changed files with 10 additions and 0 deletions

View File

@ -108,6 +108,7 @@ type Terminal struct {
damageMutex sync.Mutex
writeMutex sync.Mutex
readMutex sync.Mutex
closeMutex sync.Mutex
OnClose func(err error)
OnEvent func(event tcell.Event) bool
@ -178,6 +179,9 @@ func (term *Terminal) flushTerminal() {
}
func (term *Terminal) Close(err error) {
term.closeMutex.Lock()
defer term.closeMutex.Unlock()
if term.closed {
return
}
@ -199,6 +203,9 @@ func (term *Terminal) Close(err error) {
}
func (term *Terminal) Destroy() {
term.closeMutex.Lock()
defer term.closeMutex.Unlock()
if term.destroyed {
return
}
@ -228,6 +235,9 @@ func (term *Terminal) invalidate() {
}
func (term *Terminal) Draw(ctx *ui.Context) {
term.closeMutex.Lock()
defer term.closeMutex.Unlock()
if term.destroyed {
return
}