summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoni Marti <koni.marti@gmail.com>2022-07-26 15:41:14 +0200
committerRobin Jarry <robin@jarry.cc>2022-07-26 22:22:53 +0200
commit866867c6160b2701a2ddd74480d2a62d15b2ffe6 (patch)
tree1640ef50df7cbdc43646eebffc4c551a2ee54b75
parent54a0a377e03074a27d7d9e84092487c55761b510 (diff)
downloadaerc-866867c6160b2701a2ddd74480d2a62d15b2ffe6.zip
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>
-rw-r--r--lib/msgstore.go22
-rw-r--r--widgets/msglist.go2
2 files changed, 19 insertions, 5 deletions
diff --git a/lib/msgstore.go b/lib/msgstore.go
index 9d7f3af..32acfb4 100644
--- a/lib/msgstore.go
+++ b/lib/msgstore.go
@@ -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)
}
diff --git a/widgets/msglist.go b/widgets/msglist.go
index 95dfa1f..23eb410 100644
--- a/widgets/msglist.go
+++ b/widgets/msglist.go
@@ -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-- {