blob: 25bf0875b1a8f1a874e22f98ea9ec2947be8f65e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
package imap
import (
"sync"
"github.com/emersion/go-imap"
)
type mailboxes struct {
mb map[string]*imap.MailboxInfo
mu sync.RWMutex
changeLocks map[string]chan struct{}
}
func (mbs *mailboxes) unlocking(elem Folder) {
mbs.mu.Lock()
defer mbs.mu.Unlock()
ch, ok := mbs.changeLocks[elem.str]
if !ok {
panic("Unlocking where nothing is locked")
}
close(ch)
delete(mbs.changeLocks, elem.str)
}
func (mbs *mailboxes) locking(elem Folder) bool {
mbs.mu.Lock()
// check again, if the folder has been created in the meantime
_, ok := mbs.mb[elem.str]
if ok {
mbs.mu.Unlock()
return true
}
ch, ok := mbs.changeLocks[elem.str]
if !ok {
ch = make(chan struct{})
mbs.changeLocks[elem.str] = ch
mbs.mu.Unlock()
// we created the lock, we are in charge and done here
return false
} else {
// someone else is working, we wait till he's done
mbs.mu.Unlock() // we are not doing anything...
<-ch
return true
}
}
func (mbs *mailboxes) contains(elem Folder) bool {
mbs.mu.RLock()
defer mbs.mu.RUnlock()
_, ok := mbs.mb[elem.str]
return ok
}
func (mbs *mailboxes) add(elem *imap.MailboxInfo) {
mbs.mu.Lock()
defer mbs.mu.Unlock()
mbs.mb[elem.Name] = elem
}
func NewMailboxes() *mailboxes {
return &mailboxes{
mb: map[string]*imap.MailboxInfo{},
changeLocks: map[string]chan struct{}{},
mu: sync.RWMutex{},
}
}
|