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 return dirInfo
}
--
2.34.1
wagner riffel, Feb 26, 2022 at 03:02:
> 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!