Fix infinite watch threads spawning

Watch threads were launched every time the account's online status was
checked, added a check to only do it when it was previously offline.
sql
Manos Pitsidianakis 2019-11-07 19:12:06 +02:00
parent 749d453f00
commit 7936aef476
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
4 changed files with 33 additions and 27 deletions

View File

@ -232,9 +232,9 @@ impl MailBackend for ImapType {
work_context,
};
if has_idle {
idle(kit);
idle(kit).ok().take();
} else {
poll_with_examine(kit);
poll_with_examine(kit).ok().take();
}
})?;
Ok(handle.thread().id())

View File

@ -40,14 +40,14 @@ macro_rules! exit_on_error {
$work_context.set_status.send(($thread_id, e.to_string())).unwrap();
$sender.send(RefreshEvent {
hash: $folder_hash,
kind: RefreshEventKind::Failure(e),
kind: RefreshEventKind::Failure(e.clone()),
});
std::process::exit(1);
})+
Err(e)
} else { Ok(()) }?;)+
};
}
pub fn poll_with_examine(kit: ImapWatchKit) {
pub fn poll_with_examine(kit: ImapWatchKit) -> Result<()> {
debug!("poll with examine");
let ImapWatchKit {
is_online,
@ -89,15 +89,16 @@ pub fn poll_with_examine(kit: ImapWatchKit) {
&hash_index,
&uid_index,
&work_context,
);
)?;
}
let mut main_conn = main_conn.lock().unwrap();
main_conn.send_command(b"NOOP").unwrap();
main_conn.read_response(&mut response).unwrap();
}
Ok(())
}
pub fn idle(kit: ImapWatchKit) {
pub fn idle(kit: ImapWatchKit) -> Result<()> {
debug!("IDLE");
/* IDLE only watches the connection's selected mailbox. We will IDLE on INBOX and every ~5
* minutes wake up and poll the others */
@ -464,6 +465,7 @@ pub fn idle(kit: ImapWatchKit) {
.unwrap();
}
}
Ok(())
}
fn examine_updates(
@ -473,7 +475,7 @@ fn examine_updates(
hash_index: &Arc<Mutex<FnvHashMap<EnvelopeHash, (UID, FolderHash)>>>,
uid_index: &Arc<Mutex<FnvHashMap<usize, EnvelopeHash>>>,
work_context: &WorkContext,
) {
) -> Result<()> {
let thread_id: std::thread::ThreadId = std::thread::current().id();
let folder_hash = folder.hash();
debug!("examining folder {} {}", folder_hash, folder.path());
@ -627,4 +629,5 @@ fn examine_updates(
panic!("could not select mailbox");
}
};
Ok(())
}

View File

@ -142,7 +142,7 @@ impl MailboxEntry {
pub struct Account {
pub index: usize,
name: String,
is_online: bool,
pub is_online: bool,
pub(crate) folders: FnvHashMap<FolderHash, MailboxEntry>,
pub(crate) folder_confs: FnvHashMap<FolderHash, FolderConf>,
pub(crate) folders_order: Vec<FolderHash>,

View File

@ -144,25 +144,28 @@ impl Context {
ref mut mailbox_hashes,
..
} = self;
let was_online = accounts[account_pos].is_online;
if accounts[account_pos].is_online() {
for folder in accounts[account_pos]
.backend
.read()
.unwrap()
.folders()
.values()
{
debug!("hash & folder: {:?} {}", folder.hash(), folder.name());
mailbox_hashes.insert(folder.hash(), account_pos);
if !was_online {
for folder in accounts[account_pos]
.backend
.read()
.unwrap()
.folders()
.values()
{
debug!("hash & folder: {:?} {}", folder.hash(), folder.name());
mailbox_hashes.insert(folder.hash(), account_pos);
}
/* Account::watch() needs
* - work_controller to pass `work_context` to the watcher threads and then add them
* to the controller's static thread list,
* - sender to pass a RefreshEventConsumer closure to watcher threads for them to
* inform the main binary that refresh events arrived
* - replies to report any failures to the user
*/
accounts[account_pos].watch((work_controller, sender, replies));
}
/* Account::watch() needs
* - work_controller to pass `work_context` to the watcher threads and then add them
* to the controller's static thread list,
* - sender to pass a RefreshEventConsumer closure to watcher threads for them to
* inform the main binary that refresh events arrived
* - replies to report any failures to the user
*/
accounts[account_pos].watch((work_controller, sender, replies));
true
} else {
false