summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoni Marti <koni.marti@gmail.com>2022-05-23 22:16:13 +0200
committerRobin Jarry <robin@jarry.cc>2022-05-23 22:31:15 +0200
commit1bac87e80414f8e787c54f7f4cd2a3920aa1a095 (patch)
tree0df1fb7d749b2d91b15cf1a45d1d9560c0014100
parentf4d4e2b4e1733c1c5257a54e2fa9de2a2a2f5f28 (diff)
downloadaerc-1bac87e80414f8e787c54f7f4cd2a3920aa1a095.zip
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>
-rw-r--r--widgets/terminal.go10
1 files changed, 10 insertions, 0 deletions
diff --git a/widgets/terminal.go b/widgets/terminal.go
index 5baaec2..cd265f6 100644
--- a/widgets/terminal.go
+++ b/widgets/terminal.go
@@ -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
}