imap: prevent deadlock in watch::examine_updates

uid_store.mailboxes was locked before calling examine_updates, which
calls examine_mailbox() which also attempts to lock uid_store.mailboxes
This commit is contained in:
Manos Pitsidianakis 2020-07-17 22:45:25 +03:00
parent 996abd323f
commit 0a7f283582
No known key found for this signature in database
GPG Key ID: 73627C2F690DF710
2 changed files with 12 additions and 6 deletions

View File

@ -230,7 +230,7 @@ impl MailBackend for ImapType {
.map(std::clone::Clone::clone)
.unwrap();
let mut conn = main_conn.lock().await;
watch::examine_updates(&inbox, &mut conn, &uid_store).await?;
watch::examine_updates(inbox, &mut conn, &uid_store).await?;
Ok(())
}))
}

View File

@ -60,8 +60,11 @@ pub async fn poll_with_examine(kit: ImapWatchKit) -> Result<()> {
conn.connect().await?;
let mut response = String::with_capacity(8 * 1024);
loop {
let mailboxes = uid_store.mailboxes.lock().await;
for mailbox in mailboxes.values() {
let mailboxes: HashMap<MailboxHash, ImapMailbox> = {
let mailboxes_lck = uid_store.mailboxes.lock().await;
mailboxes_lck.clone()
};
for (_, mailbox) in mailboxes {
examine_updates(mailbox, &mut conn, &uid_store).await?;
}
let mut main_conn = main_conn.lock().await;
@ -188,8 +191,11 @@ pub async fn idle(kit: ImapWatchKit) -> Result<()> {
if now.duration_since(watch) >= _5_MINS {
/* Time to poll all inboxes */
let mut conn = main_conn.lock().await;
let mailboxes = uid_store.mailboxes.lock().await;
for mailbox in mailboxes.values() {
let mailboxes: HashMap<MailboxHash, ImapMailbox> = {
let mailboxes_lck = uid_store.mailboxes.lock().await;
mailboxes_lck.clone()
};
for (_, mailbox) in mailboxes {
exit_on_error!(
conn,
mailbox_hash,
@ -505,7 +511,7 @@ pub async fn idle(kit: ImapWatchKit) -> Result<()> {
}
pub async fn examine_updates(
mailbox: &ImapMailbox,
mailbox: ImapMailbox,
conn: &mut ImapConnection,
uid_store: &Arc<UIDStore>,
) -> Result<()> {