diff options
author | Simon Ser <contact@emersion.fr> | 2019-04-28 13:26:38 +0000 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2019-04-29 09:49:48 -0400 |
commit | a275f65848f2c1fdd4302f56121defc408e7d8b6 (patch) | |
tree | 13dfcf8e26f904f2de3d2c494b90c4f6c2fd8be0 /lib/msgstore.go | |
parent | f1698a337eb2b511835cd6cc38bf76d8e776ffa1 (diff) | |
download | aerc-a275f65848f2c1fdd4302f56121defc408e7d8b6.zip |
lib/msgstore: protect with a mutex
MessageStore has a lot of exported fields that can be read from the outside.
Each read must be protected, because a call from Update could happen at any
time.
Diffstat (limited to 'lib/msgstore.go')
-rw-r--r-- | lib/msgstore.go | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/lib/msgstore.go b/lib/msgstore.go index 9d537fc..b39d0bb 100644 --- a/lib/msgstore.go +++ b/lib/msgstore.go @@ -2,6 +2,7 @@ package lib import ( "io" + "sync" "time" "github.com/emersion/go-imap" @@ -9,7 +10,10 @@ import ( "git.sr.ht/~sircmpwn/aerc2/worker/types" ) +// Accesses to fields must be guarded by MessageStore.Lock/Unlock type MessageStore struct { + sync.Mutex + Deleted map[uint32]interface{} DirInfo types.DirectoryInfo Messages map[uint32]*types.MessageInfo @@ -45,6 +49,9 @@ func NewMessageStore(worker *types.Worker, func (store *MessageStore) FetchHeaders(uids []uint32, cb func(*types.MessageInfo)) { + store.Lock() + defer store.Unlock() + // TODO: this could be optimized by pre-allocating toFetch and trimming it // at the end. In practice we expect to get most messages back in one frame. var toFetch imap.SeqSet @@ -67,6 +74,9 @@ func (store *MessageStore) FetchHeaders(uids []uint32, } func (store *MessageStore) FetchFull(uids []uint32, cb func(io.Reader)) { + store.Lock() + defer store.Unlock() + // TODO: this could be optimized by pre-allocating toFetch and trimming it // at the end. In practice we expect to get most messages back in one frame. var toFetch imap.SeqSet @@ -103,8 +113,7 @@ func (store *MessageStore) FetchBodyPart( }) } -func (store *MessageStore) merge( - to *types.MessageInfo, from *types.MessageInfo) { +func merge(to *types.MessageInfo, from *types.MessageInfo) { if from.BodyStructure != nil { to.BodyStructure = from.BodyStructure @@ -125,6 +134,8 @@ func (store *MessageStore) merge( } func (store *MessageStore) Update(msg types.WorkerMessage) { + store.Lock() + update := false switch msg := msg.(type) { case *types.DirectoryInfo: @@ -144,7 +155,7 @@ func (store *MessageStore) Update(msg types.WorkerMessage) { update = true case *types.MessageInfo: if existing, ok := store.Messages[msg.Uid]; ok && existing != nil { - store.merge(existing, msg) + merge(existing, msg) } else { store.Messages[msg.Uid] = msg } @@ -186,6 +197,9 @@ func (store *MessageStore) Update(msg types.WorkerMessage) { store.Uids = uids update = true } + + store.Unlock() + if update { store.update() } @@ -202,11 +216,16 @@ func (store *MessageStore) update() { } func (store *MessageStore) Delete(uids []uint32) { + store.Lock() + var set imap.SeqSet for _, uid := range uids { set.AddNum(uid) store.Deleted[uid] = nil } + + store.Unlock() + store.worker.PostAction(&types.DeleteMessages{Uids: set}, nil) store.update() } |