Fix a data race due dirInfo pointer being read in the main goroutine
by NewMessageStore and written in the annonymous goroutine launched in
Worker.getDirectoryInfo.
Signed-off-by: wagner riffel <w@104d.net>
---
worker/maildir/worker.go | 53 +++++++++++++++++++---------------------
1 file changed, 25 insertions(+), 28 deletions(-)
diff --git a/worker/maildir/worker.go b/worker/maildir/worker.go
index 6ff66b2..03ffd6b 100644
--- a/worker/maildir/worker.go+++ b/worker/maildir/worker.go
@@ -145,36 +145,33 @@ func (w *Worker) getDirectoryInfo(name string) *models.DirectoryInfo {
dirInfo.Exists = len(uids)
- go func() {- info := dirInfo- for _, uid := range uids {- message, err := w.c.Message(dir, uid)- if err != nil {- w.worker.Logger.Printf("could not get message: %v", err)- continue- }- flags, err := message.Flags()- if err != nil {- w.worker.Logger.Printf("could not get flags: %v", err)- continue- }- seen := false- for _, flag := range flags {- if flag == maildir.FlagSeen {- seen = true- }- }- if !seen {- info.Unseen++- }- if w.c.IsRecent(uid) {- info.Recent+++ for _, uid := range uids {+ message, err := w.c.Message(dir, uid)+ if err != nil {+ w.worker.Logger.Printf("could not get message: %v", err)+ continue+ }+ flags, err := message.Flags()+ if err != nil {+ w.worker.Logger.Printf("could not get flags: %v", err)+ continue+ }+ seen := false+ for _, flag := range flags {+ if flag == maildir.FlagSeen {+ seen = true }
}
- info.Unseen += info.Recent- info.Exists += info.Recent- info.AccurateCounts = true- }()+ if !seen {+ dirInfo.Unseen+++ }+ if w.c.IsRecent(uid) {+ dirInfo.Recent+++ }+ }+ dirInfo.Unseen += dirInfo.Recent+ dirInfo.Exists += dirInfo.Recent+ dirInfo.AccurateCounts = true
This is almost a revert of a commit I made recently to fix a performance
problem when opening maildir folders containing large number of
messages:
https://git.sr.ht/~rjarry/aerc/commit/622802d3a5ea980b2d08ff
I agree that there is likely a data race but could we find a fix that
preserves the original fix? Maybe allow incremental dirinfo using
a channel to keep the app responsive.
Thanks!