diff --git a/melib/src/backends/imap.rs b/melib/src/backends/imap.rs index ac1a50f2..8cc7aed3 100644 --- a/melib/src/backends/imap.rs +++ b/melib/src/backends/imap.rs @@ -44,7 +44,7 @@ use fnv::{FnvHashMap, FnvHashSet}; use std::collections::hash_map::DefaultHasher; use std::hash::Hasher; use std::str::FromStr; -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, Mutex, RwLock}; pub type UID = usize; pub static SUPPORTED_CAPABILITIES: &'static [&'static str] = &["IDLE"]; @@ -100,7 +100,7 @@ pub struct ImapType { server_conf: ImapServerConf, uid_store: Arc, - folders: Arc>>, + folders: Arc>>, } impl MailBackend for ImapType { @@ -125,7 +125,7 @@ impl MailBackend for ImapType { let folder_path = folder.path().to_string(); let folder_hash = folder.hash(); let (permissions, folder_exists) = { - let f = &self.folders.lock().unwrap()[&folder_hash]; + let f = &self.folders.read().unwrap()[&folder_hash]; (f.permissions.clone(), f.exists.clone()) }; let connection = self.connection.clone(); @@ -270,13 +270,16 @@ impl MailBackend for ImapType { } fn folders(&self) -> FnvHashMap { - let mut folders = self.folders.lock().unwrap(); - if !folders.is_empty() { - return folders - .iter() - .map(|(h, f)| (*h, Box::new(Clone::clone(f)) as Folder)) - .collect(); + { + let folders = self.folders.read().unwrap(); + if !folders.is_empty() { + return folders + .iter() + .map(|(h, f)| (*h, Box::new(Clone::clone(f)) as Folder)) + .collect(); + } } + let mut folders = self.folders.write().unwrap(); *folders = ImapType::imap_folders(&self.connection); folders.retain(|_, f| (self.is_subscribed)(f.path())); let keys = folders.keys().cloned().collect::>(); @@ -294,7 +297,7 @@ impl MailBackend for ImapType { let (uid, folder_hash) = self.uid_store.hash_index.lock().unwrap()[&hash]; Box::new(ImapOp::new( uid, - self.folders.lock().unwrap()[&folder_hash] + self.folders.read().unwrap()[&folder_hash] .path() .to_string(), self.connection.clone(), @@ -304,7 +307,7 @@ impl MailBackend for ImapType { fn save(&self, bytes: &[u8], folder: &str, flags: Option) -> Result<()> { let path = { - let folders = self.folders.lock().unwrap(); + let folders = self.folders.read().unwrap(); let f_result = folders.values().find(|v| v.name == folder); if f_result @@ -349,7 +352,7 @@ impl MailBackend for ImapType { match ( &op, self.folders - .lock() + .read() .unwrap() .values() .any(|f| f.path == path), @@ -472,7 +475,7 @@ impl ImapType { server_conf, is_subscribed: Arc::new(IsSubscribedFn(is_subscribed)), - folders: Arc::new(Mutex::new(Default::default())), + folders: Arc::new(RwLock::new(Default::default())), connection: Arc::new(Mutex::new(connection)), uid_store: Arc::new(UIDStore { uidvalidity: Default::default(), @@ -575,7 +578,7 @@ impl ImapType { query: String, folder_hash: FolderHash, ) -> Result> { - let folders_lck = self.folders.lock()?; + let folders_lck = self.folders.read()?; let mut response = String::with_capacity(8 * 1024); let mut conn = self.connection.lock()?; conn.send_command(format!("EXAMINE {}", folders_lck[&folder_hash].path()).as_bytes())?; diff --git a/melib/src/backends/imap/watch.rs b/melib/src/backends/imap/watch.rs index c4a4afa2..b827300d 100644 --- a/melib/src/backends/imap/watch.rs +++ b/melib/src/backends/imap/watch.rs @@ -19,7 +19,7 @@ * along with meli. If not, see . */ use super::*; -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, Mutex, RwLock}; /// Arguments for IMAP watching functions pub struct ImapWatchKit { @@ -27,7 +27,7 @@ pub struct ImapWatchKit { pub is_online: Arc>, pub main_conn: Arc>, pub uid_store: Arc, - pub folders: Arc>>, + pub folders: Arc>>, pub sender: RefreshEventConsumer, pub work_context: WorkContext, } @@ -71,7 +71,7 @@ pub fn poll_with_examine(kit: ImapWatchKit) -> Result<()> { .send((thread_id, "sleeping...".to_string())) .unwrap(); std::thread::sleep(std::time::Duration::from_millis(5 * 60 * 1000)); - let folders = folders.lock().unwrap(); + let folders = folders.read().unwrap(); for folder in folders.values() { work_context .set_status @@ -109,7 +109,7 @@ pub fn idle(kit: ImapWatchKit) -> Result<()> { } let thread_id: std::thread::ThreadId = std::thread::current().id(); let folder: ImapFolder = folders - .lock() + .read() .unwrap() .values() .find(|f| f.parent.is_none() && f.path().eq_ignore_ascii_case("INBOX")) @@ -207,7 +207,7 @@ pub fn idle(kit: ImapWatchKit) -> Result<()> { if now.duration_since(watch) >= _5_mins { /* Time to poll all inboxes */ let mut conn = main_conn.lock().unwrap(); - for folder in folders.lock().unwrap().values() { + for folder in folders.read().unwrap().values() { work_context .set_status .send((