From 72983c6ec9baaac5bd80712cbdd9c4e83b760027 Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Tue, 7 Mar 2023 07:56:41 -0600 Subject: statusline: avoid races when updating status stack The statusline stack is written and read from separate goroutines without a lock. Make the statusline thread-safe by adding locks for access to the stack. Signed-off-by: Tim Culverhouse Acked-by: Robin Jarry --- widgets/status.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/widgets/status.go b/widgets/status.go index 00877ee2..209348c5 100644 --- a/widgets/status.go +++ b/widgets/status.go @@ -2,6 +2,7 @@ package widgets import ( "bytes" + "sync" "time" "github.com/gdamore/tcell/v2" @@ -15,6 +16,7 @@ import ( ) type StatusLine struct { + sync.Mutex stack []*StatusMessage aerc *Aerc acct *AccountView @@ -31,6 +33,8 @@ func (status *StatusLine) Invalidate() { } func (status *StatusLine) Draw(ctx *ui.Context) { + status.Lock() + defer status.Unlock() style := status.uiConfig().GetStyle(config.STYLE_STATUSLINE_DEFAULT) ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', style) switch { @@ -95,6 +99,8 @@ func (status *StatusLine) Clear() { } func (status *StatusLine) Push(text string, expiry time.Duration) *StatusMessage { + status.Lock() + defer status.Unlock() log.Debugf(text) msg := &StatusMessage{ style: status.uiConfig().GetStyle(config.STYLE_STATUSLINE_DEFAULT), @@ -105,6 +111,8 @@ func (status *StatusLine) Push(text string, expiry time.Duration) *StatusMessage defer log.PanicHandler() time.Sleep(expiry) + status.Lock() + defer status.Unlock() for i, m := range status.stack { if m == msg { status.stack = append(status.stack[:i], status.stack[i+1:]...) @@ -139,6 +147,8 @@ func (status *StatusLine) PushSuccess(text string) *StatusMessage { } func (status *StatusLine) Expire() { + status.Lock() + defer status.Unlock() status.stack = nil } -- cgit v1.2.3-54-g00ecf