threads: fix race warnings for client-side debouncing

Client-side thread debouncing happens in a different goroutine. Any
function or variable that is called or accessed by this goroutine should
be protected from a concurrent access.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
Koni Marti 2022-07-26 15:41:14 +02:00 committed by Robin Jarry
parent 54a0a377e0
commit 866867c616
2 changed files with 19 additions and 5 deletions

View file

@ -2,6 +2,7 @@ package lib
import (
"io"
"sync"
"time"
"git.sr.ht/~rjarry/aerc/lib/sort"
@ -19,7 +20,7 @@ type MessageStore struct {
// Ordered list of known UIDs
uids []uint32
Threads []*types.Thread
threads []*types.Thread
selectedUid uint32
reselect *models.MessageInfo
@ -56,6 +57,8 @@ type MessageStore struct {
threadBuilderDebounce *time.Timer
threadBuilderDelay time.Duration
threadsMutex sync.Mutex
}
const MagicUid = 0xFFFFFFFF
@ -238,7 +241,7 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
store.Messages = newMap
store.uids = uids
store.checkMark()
store.Threads = msg.Threads
store.threads = msg.Threads
update = true
case *types.MessageInfo:
if existing, ok := store.Messages[msg.Info.Uid]; ok && existing != nil {
@ -313,7 +316,7 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
}
store.results = newResults
for _, thread := range store.Threads {
for _, thread := range store.Threads() {
thread.Walk(func(t *types.Thread, _ int, _ error) error {
if _, deleted := toDelete[t.Uid]; deleted {
t.Deleted = true
@ -369,6 +372,12 @@ func (store *MessageStore) SetThreadedView(thread bool) {
store.Sort(store.sortCriteria, nil)
}
func (store *MessageStore) Threads() []*types.Thread {
store.threadsMutex.Lock()
defer store.threadsMutex.Unlock()
return store.threads
}
func (store *MessageStore) ThreadedView() bool {
return store.threadedView
}
@ -390,7 +399,12 @@ func (store *MessageStore) runThreadBuilder() {
}
}
store.threadBuilderDebounce = time.AfterFunc(store.threadBuilderDelay, func() {
store.Threads = store.builder.Threads(store.uids)
th := store.builder.Threads(store.uids)
store.threadsMutex.Lock()
store.threads = th
store.threadsMutex.Unlock()
if store.onUpdate != nil {
store.onUpdate(store)
}

View file

@ -88,7 +88,7 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
)
if store.ThreadedView() {
threads := store.Threads
threads := store.Threads()
counter := len(store.Uids())
for i := len(threads) - 1; i >= 0; i-- {