notmuch/maildir: remove double emit of the dirinfo

There was some bug which could be worked around by double emitting an event.
However that proofed to be brittle:

We send the first message here from the worker goroutine:
https://git.sr.ht/~sircmpwn/aerc/tree/a5553438/item/worker/maildir/worker.g=
o#L306

Then Tick() is waked in the main goroutine and calls ProcessMessage:
https://git.sr.ht/~sircmpwn/aerc/tree/a5553438/item/widgets/account.go#L100

ProcessMessage in the main goroutine reads types.Message state with
msg.getId() and msg.InResponseTo():
https://git.sr.ht/~sircmpwn/aerc/tree/a5553438/item/worker/types/worker.go#=
L74-76

Meanwhile in the worker goroutine we call PostMessage for a second
time with a pointer that points to the *same* previous message that
ProcessMessage is reading:
https://git.sr.ht/~sircmpwn/aerc/tree/a5553438/item/worker/maildir/worker.g=
o#L306

The second PostMessage call makes writes to message while
ProcessMessage in the main goroutine is possibly reading:
https://git.sr.ht/~sircmpwn/aerc/tree/a5553438/item/worker/types/worker.go#=
L59

This led to a data race in the event loop

Reported-By: Wagner Riffel <w@104d.net>
This commit is contained in:
Reto Brunner 2021-04-26 21:36:00 +02:00
parent 60c5a82a76
commit 1687e558d3
2 changed files with 3 additions and 7 deletions

View File

@ -299,12 +299,10 @@ func (w *Worker) handleOpenDirectory(msg *types.OpenDirectory) error {
return fmt.Errorf("could not clean directory: %v", err) return fmt.Errorf("could not clean directory: %v", err)
} }
// TODO: why does this need to be sent twice??
info := &types.DirectoryInfo{ info := &types.DirectoryInfo{
Info: w.getDirectoryInfo(msg.Directory), Info: w.getDirectoryInfo(msg.Directory),
} }
w.worker.PostMessage(info, nil) w.worker.PostMessage(info, nil)
w.worker.PostMessage(info, nil)
return nil return nil
} }

View File

@ -251,8 +251,6 @@ func (w *worker) handleOpenDirectory(msg *types.OpenDirectory) error {
return err return err
} }
info.Message = types.RespondTo(msg) info.Message = types.RespondTo(msg)
//TODO: why does this need to be sent twice??
w.w.PostMessage(info, nil)
w.w.PostMessage(info, nil) w.w.PostMessage(info, nil)
w.done(msg) w.done(msg)
return nil return nil