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:
parent
54a0a377e0
commit
866867c616
|
@ -2,6 +2,7 @@ package lib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.sr.ht/~rjarry/aerc/lib/sort"
|
"git.sr.ht/~rjarry/aerc/lib/sort"
|
||||||
|
@ -19,7 +20,7 @@ type MessageStore struct {
|
||||||
|
|
||||||
// Ordered list of known UIDs
|
// Ordered list of known UIDs
|
||||||
uids []uint32
|
uids []uint32
|
||||||
Threads []*types.Thread
|
threads []*types.Thread
|
||||||
|
|
||||||
selectedUid uint32
|
selectedUid uint32
|
||||||
reselect *models.MessageInfo
|
reselect *models.MessageInfo
|
||||||
|
@ -56,6 +57,8 @@ type MessageStore struct {
|
||||||
|
|
||||||
threadBuilderDebounce *time.Timer
|
threadBuilderDebounce *time.Timer
|
||||||
threadBuilderDelay time.Duration
|
threadBuilderDelay time.Duration
|
||||||
|
|
||||||
|
threadsMutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
const MagicUid = 0xFFFFFFFF
|
const MagicUid = 0xFFFFFFFF
|
||||||
|
@ -238,7 +241,7 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
|
||||||
store.Messages = newMap
|
store.Messages = newMap
|
||||||
store.uids = uids
|
store.uids = uids
|
||||||
store.checkMark()
|
store.checkMark()
|
||||||
store.Threads = msg.Threads
|
store.threads = msg.Threads
|
||||||
update = true
|
update = true
|
||||||
case *types.MessageInfo:
|
case *types.MessageInfo:
|
||||||
if existing, ok := store.Messages[msg.Info.Uid]; ok && existing != nil {
|
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
|
store.results = newResults
|
||||||
|
|
||||||
for _, thread := range store.Threads {
|
for _, thread := range store.Threads() {
|
||||||
thread.Walk(func(t *types.Thread, _ int, _ error) error {
|
thread.Walk(func(t *types.Thread, _ int, _ error) error {
|
||||||
if _, deleted := toDelete[t.Uid]; deleted {
|
if _, deleted := toDelete[t.Uid]; deleted {
|
||||||
t.Deleted = true
|
t.Deleted = true
|
||||||
|
@ -369,6 +372,12 @@ func (store *MessageStore) SetThreadedView(thread bool) {
|
||||||
store.Sort(store.sortCriteria, nil)
|
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 {
|
func (store *MessageStore) ThreadedView() bool {
|
||||||
return store.threadedView
|
return store.threadedView
|
||||||
}
|
}
|
||||||
|
@ -390,7 +399,12 @@ func (store *MessageStore) runThreadBuilder() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
store.threadBuilderDebounce = time.AfterFunc(store.threadBuilderDelay, func() {
|
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 {
|
if store.onUpdate != nil {
|
||||||
store.onUpdate(store)
|
store.onUpdate(store)
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
|
||||||
)
|
)
|
||||||
|
|
||||||
if store.ThreadedView() {
|
if store.ThreadedView() {
|
||||||
threads := store.Threads
|
threads := store.Threads()
|
||||||
counter := len(store.Uids())
|
counter := len(store.Uids())
|
||||||
|
|
||||||
for i := len(threads) - 1; i >= 0; i-- {
|
for i := len(threads) - 1; i >= 0; i-- {
|
||||||
|
|
Loading…
Reference in New Issue