~rjarry/aerc-devel

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
1

[PATCH] maildir: fix data race in worker

Details
Message ID
<20220226020215.68531-1-w@104d.net>
DKIM signature
missing
Download raw message
Patch: +25 -28
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
Details
Message ID
<CI77WUX6XSUB.2YO5JCXL4GQ4Z@ringo>
In-Reply-To
<20220226020215.68531-1-w@104d.net> (view parent)
DKIM signature
missing
Download raw message
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!
Reply to thread Export thread (mbox)