msgstore: fix deadlock in thread builder

When scrolling while the thread builder is running, aerc freezes. This
issue can be easily reproduced by keeping the down arrow pressed while
a folder is loading with local threading enabled.

This is caused by the threadCallback function calling store.Select which
acquires threadsMutex. However, threadCallback is already called with
threadsMutex acquired, causing a deadlock.

Fix the issue by adding a new selectPriv function that does not acquire
the lock and call this one in threadCallback *and* store.Select. Do not
reset threadCallback to nil as it was before.

Fixes: 6b8e0b19d3 ("split: refactor to prevent stuck splits")
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Thomas Vigouroux <me@vigoux.giize.com>
This commit is contained in:
Robin Jarry
2023-01-02 17:52:58 +01:00
parent fdb4b27213
commit ddfa5cac1f

View File

@@ -613,6 +613,10 @@ func (store *MessageStore) Select(uid uint32) {
store.threadCallback = nil
}
store.threadsMutex.Unlock()
store.selectPriv(uid)
}
func (store *MessageStore) selectPriv(uid uint32) {
store.selectedUid = uid
if store.marker != nil {
store.marker.UpdateVisualMark()
@@ -647,7 +651,7 @@ func (store *MessageStore) NextPrev(delta int) {
store.threadsMutex.Lock()
store.threadCallback = func() {
if uids := store.Uids(); len(uids) > newIdx {
store.Select(uids[newIdx])
store.selectPriv(uids[newIdx])
}
}
store.threadsMutex.Unlock()