Skip to content

Commit 590cf06

Browse files
committed
start IMAP loops for all transports
1 parent ebeacbe commit 590cf06

File tree

4 files changed

+62
-57
lines changed

4 files changed

+62
-57
lines changed

src/configure.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -529,12 +529,7 @@ async fn configure(ctx: &Context, param: &EnteredLoginParam) -> Result<Option<&'
529529

530530
let transport_id = 0;
531531
let (_s, r) = async_channel::bounded(1);
532-
let mut imap = Imap::new(
533-
ctx,
534-
transport_id,
535-
configured_param.clone(),
536-
r,
537-
).await?;
532+
let mut imap = Imap::new(ctx, transport_id, configured_param.clone(), r).await?;
538533
let configuring = true;
539534
let mut imap_session = match imap.connect(ctx, configuring).await {
540535
Ok(session) => session,

src/imap.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ impl Imap {
260260
let addr = &param.addr;
261261
let strict_tls = param.strict_tls(proxy_config.is_some());
262262
let oauth2 = param.oauth2;
263-
Ok( Imap {
263+
Ok(Imap {
264264
transport_id,
265265
idle_interrupt_receiver,
266266
addr: addr.to_string(),

src/scheduler.rs

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::cmp;
2-
use std::iter::{self, once};
2+
use std::iter;
33
use std::num::NonZeroUsize;
44
use std::sync::atomic::Ordering;
55

@@ -214,21 +214,25 @@ impl SchedulerState {
214214
/// Indicate that the network likely has come back.
215215
pub(crate) async fn maybe_network(&self) {
216216
let inner = self.inner.read().await;
217-
let (inbox, oboxes) = match *inner {
217+
let (inboxes, oboxes) = match *inner {
218218
InnerSchedulerState::Started(ref scheduler) => {
219219
scheduler.maybe_network();
220-
let inbox = scheduler.inbox.conn_state.state.connectivity.clone();
220+
let inboxes = scheduler
221+
.inboxes
222+
.iter()
223+
.map(|b| b.conn_state.state.connectivity.clone())
224+
.collect::<Vec<_>>();
221225
let oboxes = scheduler
222226
.oboxes
223227
.iter()
224228
.map(|b| b.conn_state.state.connectivity.clone())
225229
.collect::<Vec<_>>();
226-
(inbox, oboxes)
230+
(inboxes, oboxes)
227231
}
228232
_ => return,
229233
};
230234
drop(inner);
231-
connectivity::idle_interrupted(inbox, oboxes);
235+
connectivity::idle_interrupted(inboxes, oboxes);
232236
}
233237

234238
/// Indicate that the network likely is lost.
@@ -333,7 +337,8 @@ struct SchedBox {
333337
/// Job and connection scheduler.
334338
#[derive(Debug)]
335339
pub(crate) struct Scheduler {
336-
inbox: SchedBox,
340+
/// Inboxes, one per transport.
341+
inboxes: Vec<SchedBox>,
337342
/// Optional boxes -- mvbox.
338343
oboxes: Vec<SchedBox>,
339344
smtp: SmtpConnectionState,
@@ -860,38 +865,40 @@ impl Scheduler {
860865
let (ephemeral_interrupt_send, ephemeral_interrupt_recv) = channel::bounded(1);
861866
let (location_interrupt_send, location_interrupt_recv) = channel::bounded(1);
862867

868+
let mut inboxes = Vec::new();
863869
let mut oboxes = Vec::new();
864870
let mut start_recvs = Vec::new();
865871

866-
let (transport_id, configured_login_param) = ConfiguredLoginParam::load(ctx)
867-
.await?
868-
.context("Not configured")?;
869-
let (conn_state, inbox_handlers) =
870-
ImapConnectionState::new(ctx, transport_id, configured_login_param.clone()).await?;
871-
let (inbox_start_send, inbox_start_recv) = oneshot::channel();
872-
let handle = {
873-
let ctx = ctx.clone();
874-
task::spawn(inbox_loop(ctx, inbox_start_send, inbox_handlers))
875-
};
876-
let inbox = SchedBox {
877-
meaning: FolderMeaning::Inbox,
878-
conn_state,
879-
handle,
880-
};
881-
start_recvs.push(inbox_start_recv);
882-
883-
if ctx.should_watch_mvbox().await? {
884-
let (conn_state, handlers) = ImapConnectionState::new(ctx, transport_id, configured_login_param).await?;
885-
let (start_send, start_recv) = oneshot::channel();
886-
let ctx = ctx.clone();
887-
let meaning = FolderMeaning::Mvbox;
888-
let handle = task::spawn(simple_imap_loop(ctx, start_send, handlers, meaning));
889-
oboxes.push(SchedBox {
890-
meaning,
872+
for (transport_id, configured_login_param) in ConfiguredLoginParam::load_all(ctx).await? {
873+
let (conn_state, inbox_handlers) =
874+
ImapConnectionState::new(ctx, transport_id, configured_login_param.clone()).await?;
875+
let (inbox_start_send, inbox_start_recv) = oneshot::channel();
876+
let handle = {
877+
let ctx = ctx.clone();
878+
task::spawn(inbox_loop(ctx, inbox_start_send, inbox_handlers))
879+
};
880+
let inbox = SchedBox {
881+
meaning: FolderMeaning::Inbox,
891882
conn_state,
892883
handle,
893-
});
894-
start_recvs.push(start_recv);
884+
};
885+
inboxes.push(inbox);
886+
start_recvs.push(inbox_start_recv);
887+
888+
if ctx.should_watch_mvbox().await? {
889+
let (conn_state, handlers) =
890+
ImapConnectionState::new(ctx, transport_id, configured_login_param).await?;
891+
let (start_send, start_recv) = oneshot::channel();
892+
let ctx = ctx.clone();
893+
let meaning = FolderMeaning::Mvbox;
894+
let handle = task::spawn(simple_imap_loop(ctx, start_send, handlers, meaning));
895+
oboxes.push(SchedBox {
896+
meaning,
897+
conn_state,
898+
handle,
899+
});
900+
start_recvs.push(start_recv);
901+
}
895902
}
896903

897904
let smtp_handle = {
@@ -917,7 +924,7 @@ impl Scheduler {
917924
let recently_seen_loop = RecentlySeenLoop::new(ctx.clone());
918925

919926
let res = Self {
920-
inbox,
927+
inboxes,
921928
oboxes,
922929
smtp,
923930
smtp_handle,
@@ -937,8 +944,8 @@ impl Scheduler {
937944
Ok(res)
938945
}
939946

940-
fn boxes(&self) -> iter::Chain<iter::Once<&SchedBox>, std::slice::Iter<'_, SchedBox>> {
941-
once(&self.inbox).chain(self.oboxes.iter())
947+
fn boxes(&self) -> iter::Chain<std::slice::Iter<'_, SchedBox>, std::slice::Iter<'_, SchedBox>> {
948+
self.inboxes.iter().chain(self.oboxes.iter())
942949
}
943950

944951
fn maybe_network(&self) {
@@ -956,7 +963,9 @@ impl Scheduler {
956963
}
957964

958965
fn interrupt_inbox(&self) {
959-
self.inbox.conn_state.interrupt();
966+
for b in &self.inboxes {
967+
b.conn_state.interrupt();
968+
}
960969
}
961970

962971
fn interrupt_oboxes(&self) {
@@ -996,7 +1005,7 @@ impl Scheduler {
9961005
let timeout_duration = std::time::Duration::from_secs(30);
9971006

9981007
let tracker = TaskTracker::new();
999-
for b in once(self.inbox).chain(self.oboxes) {
1008+
for b in self.inboxes.into_iter().chain(self.oboxes.into_iter()) {
10001009
let context = context.clone();
10011010
tracker.spawn(async move {
10021011
tokio::time::timeout(timeout_duration, b.handle)

src/scheduler/connectivity.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -202,19 +202,20 @@ impl ConnectivityStore {
202202
/// Set all folder states to InterruptingIdle in case they were `Idle` before.
203203
/// Called during `dc_maybe_network()` to make sure that `all_work_done()`
204204
/// returns false immediately after `dc_maybe_network()`.
205-
pub(crate) fn idle_interrupted(inbox: ConnectivityStore, oboxes: Vec<ConnectivityStore>) {
206-
let mut connectivity_lock = inbox.0.lock();
207-
// For the inbox, we also have to set the connectivity to InterruptingIdle if it was
208-
// NotConfigured before: If all folders are NotConfigured, dc_get_connectivity()
209-
// returns Connected. But after dc_maybe_network(), dc_get_connectivity() must not
210-
// return Connected until DC is completely done with fetching folders; this also
211-
// includes scan_folders() which happens on the inbox thread.
212-
if *connectivity_lock == DetailedConnectivity::Idle
213-
|| *connectivity_lock == DetailedConnectivity::NotConfigured
214-
{
215-
*connectivity_lock = DetailedConnectivity::InterruptingIdle;
205+
pub(crate) fn idle_interrupted(inboxes: Vec<ConnectivityStore>, oboxes: Vec<ConnectivityStore>) {
206+
if let Some(inbox) = inboxes.first() {
207+
let mut connectivity_lock = inbox.0.lock();
208+
// For the inbox, we also have to set the connectivity to InterruptingIdle if it was
209+
// NotConfigured before: If all folders are NotConfigured, dc_get_connectivity()
210+
// returns Connected. But after dc_maybe_network(), dc_get_connectivity() must not
211+
// return Connected until DC is completely done with fetching folders; this also
212+
// includes scan_folders() which happens on the inbox thread.
213+
if *connectivity_lock == DetailedConnectivity::Idle
214+
|| *connectivity_lock == DetailedConnectivity::NotConfigured
215+
{
216+
*connectivity_lock = DetailedConnectivity::InterruptingIdle;
217+
}
216218
}
217-
drop(connectivity_lock);
218219

219220
for state in oboxes {
220221
let mut connectivity_lock = state.0.lock();

0 commit comments

Comments
 (0)