From d66930749a9f8eaa19acab78d57585a170f17429 Mon Sep 17 00:00:00 2001 From: Moritz Poldrack Date: Thu, 24 Mar 2022 10:47:34 +0100 Subject: [PATCH] logging: fix race condition in startup If a panic occurs in one of the workers, it can happen after the UI was initialised, but before the cleanup function has been registered. With this the start of the worker loops is deferred until the cleanup routine was registered. Signed-off-by: Moritz Poldrack --- aerc.go | 5 ++++- widgets/account-wizard.go | 2 +- widgets/account.go | 8 ++++++-- widgets/aerc.go | 6 +++--- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/aerc.go b/aerc.go index aa82f98..9d93a50 100644 --- a/aerc.go +++ b/aerc.go @@ -166,11 +166,13 @@ func main() { ui *libui.UI ) + deferLoop := make(chan struct{}) + aerc = widgets.NewAerc(conf, logger, func(cmd []string) error { return execCommand(aerc, ui, cmd) }, func(cmd string) []string { return getCompletions(aerc, cmd) - }, &commands.CmdHistory) + }, &commands.CmdHistory, deferLoop) ui, err = libui.Initialize(aerc) if err != nil { @@ -180,6 +182,7 @@ func main() { logging.UICleanup = func() { ui.Close() } + close(deferLoop) if conf.Ui.MouseEnabled { ui.EnableMouse() diff --git a/widgets/account-wizard.go b/widgets/account-wizard.go index 1645d45..42d14d1 100644 --- a/widgets/account-wizard.go +++ b/widgets/account-wizard.go @@ -535,7 +535,7 @@ func (wizard *AccountWizard) finish(tutorial bool) { wizard.conf.Accounts = append(wizard.conf.Accounts, account) view, err := NewAccountView(wizard.aerc, wizard.conf, &account, - wizard.aerc.logger, wizard.aerc) + wizard.aerc.logger, wizard.aerc, nil) if err != nil { wizard.aerc.NewTab(errorScreen(err.Error(), wizard.conf.Ui), account.Name) diff --git a/widgets/account.go b/widgets/account.go index 55c4f55..3bf104b 100644 --- a/widgets/account.go +++ b/widgets/account.go @@ -47,8 +47,8 @@ func (acct *AccountView) UiConfig() config.UIConfig { } func NewAccountView(aerc *Aerc, conf *config.AercConfig, acct *config.AccountConfig, - logger *log.Logger, host TabHost) (*AccountView, error) { - + logger *log.Logger, host TabHost, deferLoop chan struct{}, +) (*AccountView, error) { acctUiConf := conf.GetUiConfig(map[config.ContextType]string{ config.UI_CONTEXT_ACCOUNT: acct.Name, }) @@ -90,6 +90,10 @@ func NewAccountView(aerc *Aerc, conf *config.AercConfig, acct *config.AccountCon go func() { defer logging.PanicHandler() + if deferLoop != nil { + <-deferLoop + } + worker.Backend.Run() }() diff --git a/widgets/aerc.go b/widgets/aerc.go index c96932c..db447e4 100644 --- a/widgets/aerc.go +++ b/widgets/aerc.go @@ -48,8 +48,8 @@ type Choice struct { func NewAerc(conf *config.AercConfig, logger *log.Logger, cmd func(cmd []string) error, complete func(cmd string) []string, - cmdHistory lib.History) *Aerc { - + cmdHistory lib.History, deferLoop chan struct{}, +) *Aerc { tabs := ui.NewTabs(&conf.Ui) statusbar := ui.NewStack(conf.Ui) @@ -85,7 +85,7 @@ func NewAerc(conf *config.AercConfig, logger *log.Logger, conf.Triggers.ExecuteCommand = cmd for i, acct := range conf.Accounts { - view, err := NewAccountView(aerc, conf, &conf.Accounts[i], logger, aerc) + view, err := NewAccountView(aerc, conf, &conf.Accounts[i], logger, aerc, deferLoop) if err != nil { tabs.Add(errorScreen(err.Error(), conf.Ui), acct.Name) } else {