aboutsummaryrefslogtreecommitdiff
path: root/internal/imap
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--internal/imap/connection.go7
-rw-r--r--internal/imap/mailboxes.go41
2 files changed, 43 insertions, 5 deletions
diff --git a/internal/imap/connection.go b/internal/imap/connection.go
index 88b1496..358445b 100644
--- a/internal/imap/connection.go
+++ b/internal/imap/connection.go
@@ -99,6 +99,13 @@ func (conn *connection) ensureFolder(folder Folder) error {
return nil
}
+ if conn.mailboxes.locking(folder) {
+ // someone else tried to create the MB -- try again, now that he's done
+ return conn.ensureFolder(folder)
+ } else {
+ defer conn.mailboxes.unlocking(folder)
+ }
+
log.Printf("Checking for folder '%s'", folder)
mbox, found, err := conn.list(folder.str)
diff --git a/internal/imap/mailboxes.go b/internal/imap/mailboxes.go
index d0fdede..f1dc6c6 100644
--- a/internal/imap/mailboxes.go
+++ b/internal/imap/mailboxes.go
@@ -7,8 +7,38 @@ import (
)
type mailboxes struct {
- mb map[string]*imap.MailboxInfo
- mu sync.RWMutex
+ 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()
+ 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 {
@@ -28,7 +58,8 @@ func (mbs *mailboxes) add(elem *imap.MailboxInfo) {
func NewMailboxes() *mailboxes {
return &mailboxes{
- mb: map[string]*imap.MailboxInfo{},
- mu: sync.RWMutex{},
+ mb: map[string]*imap.MailboxInfo{},
+ changeLocks: map[string]chan struct{}{},
+ mu: sync.RWMutex{},
}
-} \ No newline at end of file
+}
ke umlauts in the folder name (see the > attached patch). > > Problem is, that the encode_utf7 (and the decode_utf7 FWIW) uses the > 'String::force_encoding' method, which some googling shows to be in > Ruby1.9 but not 1.8. 2010-12-01robustify config parsingLucas Nussbaum1-11/+22 2010-11-30Also add reupload_if_updated for MaildirsLucas Nussbaum1-1/+4 2010-11-30Add a reupload_if_updated option (default: true)Lucas Nussbaum4-8/+20 Following a discussion on feed2imap-devel, add a reupload_if_updated option. When set to false, if an item is updated, but was previously removed from the IMAP server, it is no longer re-uploaded. Also fix some config file parsing bugs for the disable-ssl-verification and include-images options. I should really switch to another way to describe F2I config... 2010-07-05Patch to use feed item pubDate in Maildir file namesBernie Maier1-6/+10 Hi! I've just subscribed to the list, having downloaded feed2imap a few days ago. Since I want to just write RSS feeds to a local Maildir, this looked like just what I needed. Unfortunately, the release 1.0 version seems to randomise the order of the feed items when doing the first fetch for a new feed. Looking at maildir.rb, there is a "TODO: handle `date'" comment and it looks like the code is just generating maildir filenames using the timestamp at the time the items are being written into the maildir. Since all the initial items are written at the same time, and the maildir file name has a random element, this loses the original ordering from the mail feed. The solution is to use the timestamp corresponding to the pubDate in the feed item as the initial component of the maildir file name. Also, instead of using a random integer to force uniqueness in the second component of the file name, I think it is better to use a sequence number for each feed item, which will still be unique for the feed and also preserve item order. My patch follows (it's the first piece of Ruby code I've ever written / modified)... Cheers, Bernie 2010-04-18update websiteLucas Nussbaum2-2/+15 2010-04-18prepare releaseLucas Nussbaum4-5/+5 2010-04-18provide a way to disable SSL certificate verificationLucas Nussbaum4-1/+12 2010-04-18update changelogLucas Nussbaum1-0/+4 2010-04-18Update rubyimap.rbLucas Nussbaum1-5/+38 Update rubyimap.rb to upstream revision 27336 2010-03-17Document the maildir targetSandra Snan3-5/+5 I looked for a good feed to maildir program, and I couldn’t find one. Turns out, by looking at feed2imaps source code, that it has that function. So here’s a documentation patch so it’s easier to find. This patch shouldn’t touch any code. Generated by git. Sandra Signed-off-by: Sandra Snan <sandra.snan@handgranat.org> 2009-12-26Avoid using "acme.com"Lucas Nussbaum4-10/+19 Patch from Guido Berhoerster <guido@berhoerster.name>: Hello, here is a small patch that avoids using the valid(!) domain "acme.com" for generating message ids and email addresses. It adds a new global configuration option "default-email" which will be used in case a feed does provide one, currently feed2imap resorts to "feed2imap@acme.com". If this configuration option is not given it will basically default to <logname>@<hostname> as returned by Etc.getlogin and Socket.gethostname. Yours, 2009-09-04fix to use Message-Id instead of X-CacheIndexLucas Nussbaum1-5/+2 2009-09-03added the forth arg to ConfigFeed::new for maildirLucas Nussbaum1-1/+1