Compare commits

..

3 Commits

Author SHA1 Message Date
holger krekel
844a540c57 fix error messages 2019-12-15 01:53:13 +01:00
holger krekel
eece5b9ac8 fix idle_wait.await result processing 2019-12-15 01:40:39 +01:00
holger krekel
b20c33acaa fix #1030 (asynct-smtp crash) thanks @link2xt and @dignifiedquire 2019-12-15 01:23:51 +01:00
18 changed files with 163 additions and 173 deletions

74
Cargo.lock generated
View File

@@ -85,17 +85,17 @@ dependencies = [
[[package]]
name = "async-imap"
version = "0.1.1"
source = "git+https://github.com/async-email/async-imap#d7836416766b55d8d03587ea5326eecf501c2030"
source = "git+https://github.com/async-email/async-imap#d3a502ac46cd6707d481205871ab25bb5534a362"
dependencies = [
"async-attributes 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"async-native-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-pool 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"futures_codec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"imap-proto 0.9.1 (git+https://github.com/djc/tokio-imap)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -103,15 +103,6 @@ dependencies = [
"stop-token 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "async-macros"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "async-native-tls"
version = "0.1.1"
@@ -124,10 +115,10 @@ dependencies = [
[[package]]
name = "async-smtp"
version = "0.1.0"
source = "git+https://github.com/async-email/async-smtp#4f8416a0b8e0f8369459bb2fd342e79a17eb836b"
source = "git+https://github.com/async-email/async-smtp#c26ce542e847c502654c471ebc50d6c996f86cee"
dependencies = [
"async-native-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"async-trait 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -146,10 +137,9 @@ dependencies = [
[[package]]
name = "async-std"
version = "1.2.0"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"async-macros 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"async-task 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"broadcaster 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -342,6 +332,15 @@ name = "bufstream"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byte-pool"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "byte-tools"
version = "0.3.1"
@@ -552,6 +551,14 @@ dependencies = [
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-queue"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-utils"
version = "0.6.6"
@@ -610,7 +617,7 @@ dependencies = [
"ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -640,7 +647,7 @@ dependencies = [
"async-imap 0.1.1 (git+https://github.com/async-email/async-imap)",
"async-native-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"async-smtp 0.1.0 (git+https://github.com/async-email/async-smtp)",
"async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -675,7 +682,7 @@ dependencies = [
"r2d2_sqlite 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)",
"rusqlite 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustyline 4.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sanitize-filename 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1153,17 +1160,6 @@ dependencies = [
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "futures_codec"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "generic-array"
version = "0.12.3"
@@ -2332,7 +2328,7 @@ dependencies = [
[[package]]
name = "reqwest"
version = "0.9.22"
version = "0.9.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2691,7 +2687,7 @@ name = "stop-token"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2713,7 +2709,7 @@ dependencies = [
[[package]]
name = "strsim"
version = "0.9.2"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -3321,10 +3317,9 @@ dependencies = [
"checksum ascii_utils 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a"
"checksum async-attributes 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "efd3d156917d94862e779f356c5acae312b08fd3121e792c857d7928c8088423"
"checksum async-imap 0.1.1 (git+https://github.com/async-email/async-imap)" = "<none>"
"checksum async-macros 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "644a5a8de80f2085a1e7e57cd1544a2a7438f6e003c0790999bd43b92a77cdb2"
"checksum async-native-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a29e9e4ed87f4070dd6099d0bd5edfc7692c94442c80d656b50a802c6fde23b7"
"checksum async-smtp 0.1.0 (git+https://github.com/async-email/async-smtp)" = "<none>"
"checksum async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "513ee3c49800679a319912340f5601afda9e72848d7dea3a48bab489e8c1a46f"
"checksum async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94ef4b71b2f56d7f8793c2a353fa0aa254833c55ab611dc6f3e0bd63db487e2d"
"checksum async-task 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de6bd58f7b9cc49032559422595c81cbfcf04db2f2133592f70af19e258a1ced"
"checksum async-trait 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "8b6dd385bb33043b833ba049048d57bdbb4d654a121ed68c71871ca51ff67070"
"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
@@ -3346,6 +3341,7 @@ dependencies = [
"checksum broadcaster 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "07a1446420a56f1030271649ba0da46d23239b3a68c73591cea5247f15a788a0"
"checksum buf_redux 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f"
"checksum bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8"
"checksum byte-pool 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9342e102eac8b1879fbedf9a7e0572c40b0cc5805b663c4d4ca791cae0bae221"
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
"checksum bytecount 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b92204551573580e078dc80017f36a213eb77a0450e4ddd8cfa0f3f2d1f0178f"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
@@ -3372,6 +3368,7 @@ dependencies = [
"checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca"
"checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac"
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
"checksum crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfd6515864a82d2f877b42813d4553292c6659498c9a2aa31bab5a15243c2700"
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
"checksum ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8ce37ad4184ab2ce004c33bf6379185d3b1c95801cab51026bd271bf68eedc"
@@ -3434,7 +3431,6 @@ dependencies = [
"checksum futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6"
"checksum futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76"
"checksum futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d"
"checksum futures_codec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "793d2283ff61ffff52d51cc631be0c8e75370d96056a38e09f124a67263913da"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
@@ -3561,7 +3557,7 @@ dependencies = [
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
"checksum rental 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8545debe98b2b139fb04cad8618b530e9b07c152d99a5de83c860b877d67847f"
"checksum rental-impl 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "475e68978dc5b743f2f40d8e0a8fdc83f1c5e78cbf4b8fa5e74e73beebc340de"
"checksum reqwest 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)" = "2c2064233e442ce85c77231ebd67d9eca395207dec2127fe0bbedde4bd29a650"
"checksum reqwest 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "f88643aea3c1343c804950d7bf983bd2067f5ab59db6d613a08e05572f2714ab"
"checksum ripemd160 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad5112e0dbbb87577bfbc56c42450235e3012ce336e29c5befd7807bd626da4a"
"checksum rsa 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ed8692d8e0ea3baae03f0f32ecfc13a6c6f1f85fcd6d9fdefcdf364e70f4df9"
"checksum rusqlite 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a194373ef527035645a1bc21b10dc2125f73497e6e155771233eb187aedd051"
@@ -3601,7 +3597,7 @@ dependencies = [
"checksum stop-token 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "06855fb7c94d3be9b3a57c4d82dfc8a43bb658fbb3b1dda79de89e748d9eb9dd"
"checksum stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8131256a5896cabcf5eb04f4d6dacbe1aefda854b0d9896e09cb58829ec5638c"
"checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d"
"checksum strsim 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "032c03039aae92b350aad2e3779c352e104d919cb192ba2fabbd7b831ce4f0f6"
"checksum strsim 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
"checksum strum 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6138f8f88a16d90134763314e3fc76fa3ed6a7db4725d6acf9a3ef95a3188d22"
"checksum strum_macros 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0054a7df764039a6cd8592b9de84be4bec368ff081d203a7d5371cbfa8e65c81"
"checksum subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941"

View File

@@ -509,7 +509,7 @@ pub unsafe extern "C" fn dc_interrupt_imap_idle(context: *mut dc_context_t) {
}
let ffi_context = &*context;
ffi_context
.with_inner(|ctx| job::interrupt_inbox_idle(ctx))
.with_inner(|ctx| job::interrupt_inbox_idle(ctx, true))
.unwrap_or(())
}

View File

@@ -491,7 +491,7 @@ pub fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::Error> {
println!("{:#?}", context.get_info());
}
"interrupt" => {
interrupt_inbox_idle(context);
interrupt_inbox_idle(context, true);
}
"maybenetwork" => {
maybe_network(context);

View File

@@ -202,7 +202,7 @@ fn stop_threads(context: &Context) {
println!("Stopping threads");
IS_RUNNING.store(false, Ordering::Relaxed);
interrupt_inbox_idle(context);
interrupt_inbox_idle(context, true);
interrupt_mvbox_idle(context);
interrupt_sentbox_idle(context);
interrupt_smtp_idle(context);

View File

@@ -104,7 +104,7 @@ fn main() {
println!("stopping threads");
*running.write().unwrap() = false;
deltachat::job::interrupt_inbox_idle(&ctx);
deltachat::job::interrupt_inbox_idle(&ctx, true);
deltachat::job::interrupt_smtp_idle(&ctx);
println!("joining");

View File

@@ -1352,7 +1352,7 @@ pub fn delete(context: &Context, chat_id: u32) -> Result<(), Error> {
});
job_kill_action(context, Action::Housekeeping);
add_job_with_interrupt(context, Action::Housekeeping, 0, Params::new(), 10);
job_add(context, Action::Housekeeping, 0, Params::new(), 10);
Ok(())
}

View File

@@ -143,7 +143,7 @@ impl Context {
}
Config::InboxWatch => {
let ret = self.sql.set_raw_config(self, key, value);
interrupt_inbox_idle(self);
interrupt_inbox_idle(self, true);
ret
}
Config::SentboxWatch => {

View File

@@ -38,7 +38,7 @@ pub fn configure(context: &Context) {
return;
}
job_kill_action(context, Action::ConfigureImap);
add_job_with_interrupt(context, Action::ConfigureImap, 0, Params::new(), 0);
job_add(context, Action::ConfigureImap, 0, Params::new(), 0);
}
/// Check if the context is already configured.

View File

@@ -14,11 +14,13 @@ use crate::contact::*;
use crate::error::*;
use crate::events::Event;
use crate::imap::*;
use crate::job::*;
use crate::job_thread::JobThread;
use crate::key::*;
use crate::login_param::LoginParam;
use crate::lot::Lot;
use crate::message::{self, MsgId};
use crate::message::{self, Message, MsgId};
use crate::param::Params;
use crate::smtp::Smtp;
use crate::sql::Sql;
@@ -44,6 +46,7 @@ pub struct Context {
/// Blob directory path
blobdir: PathBuf,
pub sql: Sql,
pub perform_inbox_jobs_needed: Arc<RwLock<bool>>,
pub probe_imap_network: Arc<RwLock<bool>>,
pub inbox_thread: Arc<RwLock<JobThread>>,
pub sentbox_thread: Arc<RwLock<JobThread>>,
@@ -146,6 +149,7 @@ impl Context {
Imap::new(),
))),
probe_imap_network: Arc::new(RwLock::new(false)),
perform_inbox_jobs_needed: Arc::new(RwLock::new(false)),
generating_key_mutex: Mutex::new(()),
translated_stockstrings: RwLock::new(HashMap::new()),
};
@@ -432,6 +436,34 @@ impl Context {
false
}
}
pub fn do_heuristics_moves(&self, folder: &str, msg_id: MsgId) {
if !self.get_config_bool(Config::MvboxMove) {
return;
}
if self.is_mvbox(folder) {
return;
}
if let Ok(msg) = Message::load_from_db(self, msg_id) {
if msg.is_setupmessage() {
// do not move setup messages;
// there may be a non-delta device that wants to handle it
return;
}
// 1 = dc message, 2 = reply to dc message
if 0 != msg.is_dc_message {
job_add(
self,
Action::MoveMsg,
msg.id.to_u32() as i32,
Params::new(),
0,
);
}
}
}
}
impl Drop for Context {

View File

@@ -250,7 +250,7 @@ pub fn dc_receive_imf(
// if we delete we don't need to try moving messages
if needs_delete_job && !created_db_entries.is_empty() {
add_job_no_interrupt(
job_add(
context,
Action::DeleteMsgOnImap,
created_db_entries[0].1.to_u32() as i32,
@@ -258,7 +258,7 @@ pub fn dc_receive_imf(
0,
);
} else {
crate::imap::do_heuristics_moves(context, server_folder.as_ref(), insert_msg_id);
context.do_heuristics_moves(server_folder.as_ref(), insert_msg_id);
}
info!(

View File

@@ -3,7 +3,6 @@ use super::Imap;
use async_imap::extensions::idle::IdleResponse;
use async_std::prelude::*;
use async_std::task;
use core::cmp::min;
use std::sync::atomic::Ordering;
use std::time::{Duration, SystemTime};
@@ -19,9 +18,12 @@ pub enum Error {
#[fail(display = "IMAP IDLE protocol failed to init/complete")]
IdleProtocolFailed(#[cause] async_imap::error::Error),
#[fail(display = "IMAP IDLE protocol timed out")]
#[fail(display = "IMAP IDLE protocol timeout during Termination")]
IdleTimeout(#[cause] async_std::future::TimeoutError),
#[fail(display = "IMAP Error during Idle Wait")]
IdleError(#[cause] async_imap::error::Error),
#[fail(display = "IMAP server does not have IDLE capability")]
IdleAbilityMissing,
@@ -46,12 +48,7 @@ impl Imap {
task::block_on(async move { self.config.read().await.can_idle })
}
pub fn idle(
&self,
context: &Context,
watch_folder: Option<String>,
until: SystemTime,
) -> Result<()> {
pub fn idle(&self, context: &Context, watch_folder: Option<String>) -> Result<()> {
task::block_on(async move {
if !self.can_idle() {
return Err(Error::IdleAbilityMissing);
@@ -63,18 +60,8 @@ impl Imap {
self.select_folder(context, watch_folder.clone()).await?;
let timeout = match until.duration_since(SystemTime::now()) {
Ok(timeout) => timeout,
Err(_) => {
info!(context, "idle called with negative timeout");
return Ok(());
}
};
let timeout = min(timeout, Duration::from_secs(23 * 60));
info!(context, "idle-timeout is {:?}", timeout);
let session = self.session.lock().await.take();
let timeout = Duration::from_secs(23 * 60);
if let Some(session) = session {
match session.idle() {
// BEWARE: If you change the Secure branch you
@@ -83,6 +70,7 @@ impl Imap {
if let Err(err) = handle.init().await {
return Err(Error::IdleProtocolFailed(err));
}
let (idle_wait, interrupt) = handle.wait_with_timeout(timeout);
*self.interrupt.lock().await = Some(interrupt);
@@ -95,18 +83,22 @@ impl Imap {
} else {
info!(context, "Idle entering wait-on-remote state");
match idle_wait.await {
IdleResponse::NewData(_) => {
Ok(IdleResponse::NewData(_)) => {
info!(context, "Idle has NewData");
}
// TODO: idle_wait does not distinguish manual interrupts
// from Timeouts if we would know it's a Timeout we could bail
// directly and reconnect .
IdleResponse::Timeout => {
Ok(IdleResponse::Timeout) => {
info!(context, "Idle-wait timeout or interruption");
}
IdleResponse::ManualInterrupt => {
Ok(IdleResponse::ManualInterrupt) => {
info!(context, "Idle wait was interrupted");
}
Err(err) => {
self.trigger_reconnect();
return Err(Error::IdleError(err));
}
}
}
// if we can't properly terminate the idle
@@ -149,18 +141,22 @@ impl Imap {
} else {
info!(context, "Idle entering wait-on-remote state");
match idle_wait.await {
IdleResponse::NewData(_) => {
Ok(IdleResponse::NewData(_)) => {
info!(context, "Idle has NewData");
}
// TODO: idle_wait does not distinguish manual interrupts
// from Timeouts if we would know it's a Timeout we could bail
// directly and reconnect .
IdleResponse::Timeout => {
Ok(IdleResponse::Timeout) => {
info!(context, "Idle-wait timeout or interruption");
}
IdleResponse::ManualInterrupt => {
Ok(IdleResponse::ManualInterrupt) => {
info!(context, "Idle wait was interrupted");
}
Err(err) => {
self.trigger_reconnect();
return Err(Error::IdleError(err));
}
}
}
// if we can't properly terminate the idle
@@ -193,12 +189,7 @@ impl Imap {
})
}
pub(crate) fn fake_idle(
&self,
context: &Context,
watch_folder: Option<String>,
until: SystemTime,
) {
pub(crate) fn fake_idle(&self, context: &Context, watch_folder: Option<String>) {
// Idle using polling. This is also needed if we're not yet configured -
// in this case, we're waiting for a configure job (and an interrupt).
task::block_on(async move {
@@ -233,11 +224,6 @@ impl Imap {
break;
}
info!(context, "fake_idle is connected");
if SystemTime::now() > until {
info!(context, "fake_idle stopping as jobs need running");
break;
}
// we are connected, let's see if fetching messages results
// in anything. If so, we behave as if IDLE had data but
// will have already fetched the messages so perform_*_fetch

View File

@@ -17,9 +17,9 @@ use crate::context::Context;
use crate::dc_receive_imf::dc_receive_imf;
use crate::events::Event;
use crate::imap_client::*;
use crate::job::{add_job_no_interrupt, Action};
use crate::job::{job_add, Action};
use crate::login_param::{CertificateChecks, LoginParam};
use crate::message::{self, update_server_uid, Message, MsgId};
use crate::message::{self, update_server_uid};
use crate::oauth2::dc_get_oauth2_access_token;
use crate::param::Params;
use crate::stock::StockMessage;
@@ -1202,8 +1202,8 @@ fn precheck_imf(context: &Context, rfc724_mid: &str, server_folder: &str, server
{
if old_server_folder.is_empty() && old_server_uid == 0 {
info!(context, "[move] detected bbc-self {}", rfc724_mid,);
do_heuristics_moves(context, server_folder, msg_id);
add_job_no_interrupt(
context.do_heuristics_moves(server_folder.as_ref(), msg_id);
job_add(
context,
Action::MarkseenMsgOnImap,
msg_id.to_u32() as i32,
@@ -1237,32 +1237,3 @@ fn prefetch_get_message_id(prefetch_msg: &Fetch) -> Result<String> {
wrapmime::parse_message_id(&message_id.unwrap()).map_err(Into::into)
}
pub fn do_heuristics_moves(context: &Context, folder: &str, msg_id: MsgId) {
if !context.get_config_bool(crate::config::Config::MvboxMove) {
return;
}
if context.is_mvbox(folder) {
return;
}
if let Ok(msg) = Message::load_from_db(context, msg_id) {
if msg.is_setupmessage() {
// do not move setup messages;
// there may be a non-delta device that wants to handle it
return;
}
// 1 = dc message, 2 = reply to dc message
if 0 != msg.is_dc_message {
// we are called from receive_imf so there is no idle running
add_job_no_interrupt(
context,
Action::MoveMsg,
msg.id.to_u32() as i32,
Params::new(),
0,
);
}
}
}

View File

@@ -74,7 +74,7 @@ pub fn imex(context: &Context, what: ImexMode, param1: Option<impl AsRef<Path>>)
}
job_kill_action(context, Action::ImexImap);
add_job_with_interrupt(context, Action::ImexImap, 0, param, 0);
job_add(context, Action::ImexImap, 0, param, 0);
}
/// Returns the filename of the backup found (otherwise an error)

View File

@@ -35,7 +35,7 @@ const JOB_RETRIES: u32 = 17;
/// Thread IDs
#[derive(Debug, Display, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive, FromSql, ToSql)]
#[repr(i32)]
pub enum Thread {
enum Thread {
Unknown = 0,
Imap = 100,
Smtp = 5000,
@@ -134,7 +134,7 @@ impl Job {
/// Updates the job already stored in the database.
///
/// To add a new job, use [add_job_*].
/// To add a new job, use [job_add].
fn update(&self, context: &Context) -> bool {
sql::execute(
context,
@@ -436,6 +436,13 @@ pub fn perform_sentbox_fetch(context: &Context) {
}
pub fn perform_inbox_idle(context: &Context) {
if *context.perform_inbox_jobs_needed.clone().read().unwrap() {
info!(
context,
"INBOX-IDLE will not be started because of waiting jobs."
);
return;
}
let use_network = context.get_config_bool(Config::InboxWatch);
context
@@ -465,8 +472,21 @@ pub fn perform_sentbox_idle(context: &Context) {
.idle(context, use_network);
}
pub fn interrupt_inbox_idle(context: &Context) {
context.inbox_thread.read().unwrap().interrupt_idle(context);
pub fn interrupt_inbox_idle(context: &Context, block: bool) {
info!(context, "interrupt_inbox_idle called blocking={}", block);
if block {
context.inbox_thread.read().unwrap().interrupt_idle(context);
} else {
match context.inbox_thread.try_read() {
Ok(inbox_thread) => {
inbox_thread.interrupt_idle(context);
}
Err(err) => {
*context.perform_inbox_jobs_needed.write().unwrap() = true;
warn!(context, "could not interrupt idle: {}", err);
}
}
}
}
pub fn interrupt_mvbox_idle(context: &Context) {
@@ -543,7 +563,7 @@ pub fn perform_smtp_idle(context: &Context) {
info!(context, "SMTP-idle ended.",);
}
pub(crate) fn get_next_wakeup_time(context: &Context, thread: Thread) -> Duration {
fn get_next_wakeup_time(context: &Context, thread: Thread) -> Duration {
let t: i64 = context
.sql
.query_get_value(
@@ -553,16 +573,17 @@ pub(crate) fn get_next_wakeup_time(context: &Context, thread: Thread) -> Duratio
)
.unwrap_or_default();
let mut wakeup_time = Duration::new(10 * 60, 0);
let now = time();
if t > 0 {
let now = time();
if t > now {
Duration::new((t - now) as u64, 0)
wakeup_time = Duration::new((t - now) as u64, 0);
} else {
Duration::new(0, 0)
wakeup_time = Duration::new(0, 0);
}
} else {
Duration::new(30 * 60, 0)
}
wakeup_time
}
pub fn maybe_network(context: &Context) {
@@ -575,7 +596,7 @@ pub fn maybe_network(context: &Context) {
}
interrupt_smtp_idle(context);
interrupt_inbox_idle(context);
interrupt_inbox_idle(context, true);
interrupt_mvbox_idle(context);
interrupt_sentbox_idle(context);
}
@@ -694,6 +715,7 @@ pub fn perform_inbox_jobs(context: &Context) {
let probe_imap_network = *context.probe_imap_network.clone().read().unwrap();
*context.probe_imap_network.write().unwrap() = false;
*context.perform_inbox_jobs_needed.write().unwrap() = false;
job_perform(context, Thread::Imap, probe_imap_network);
info!(context, "dc_perform_inbox_jobs ended.",);
@@ -896,7 +918,7 @@ fn add_smtp_job(
param.set(Param::File, blob.as_name());
param.set(Param::Recipients, &recipients);
add_job_with_interrupt(
job_add(
context,
action,
rendered_msg
@@ -912,7 +934,7 @@ fn add_smtp_job(
/// Adds a job to the database, scheduling it `delay_seconds`
/// after the current time.
pub fn add_job_no_interrupt(
pub fn job_add(
context: &Context,
action: Action,
foreign_id: i32,
@@ -920,7 +942,7 @@ pub fn add_job_no_interrupt(
delay_seconds: i64,
) {
if action == Action::Unknown {
error!(context, "Invalid action passed to add_job_no_interrupt");
error!(context, "Invalid action passed to job_add");
return;
}
@@ -940,20 +962,9 @@ pub fn add_job_no_interrupt(
(timestamp + delay_seconds as i64)
]
).ok();
}
pub fn add_job_with_interrupt(
context: &Context,
action: Action,
foreign_id: i32,
param: Params,
delay_seconds: i64,
) {
let thread: Thread = action.into();
add_job_no_interrupt(context, action, foreign_id, param, delay_seconds);
match thread {
Thread::Imap => interrupt_inbox_idle(context),
Thread::Imap => interrupt_inbox_idle(context, false),
Thread::Smtp => interrupt_smtp_idle(context),
Thread::Unknown => {}
}

View File

@@ -3,8 +3,6 @@ use std::sync::{Arc, Condvar, Mutex};
use crate::context::Context;
use crate::error::{Error, Result};
use crate::imap::Imap;
use crate::job::{get_next_wakeup_time, Thread};
use std::time::{Duration, SystemTime};
#[derive(Debug)]
pub struct JobThread {
@@ -59,6 +57,10 @@ impl JobThread {
}
pub fn interrupt_idle(&self, context: &Context) {
{
self.state.0.lock().unwrap().jobs_needed = true;
}
info!(context, "Interrupting {}-IDLE...", self.name);
self.imap.interrupt_idle(context);
@@ -134,23 +136,18 @@ impl JobThread {
}
pub fn idle(&self, context: &Context, use_network: bool) {
// standard idle wait timeout
let mut timeout = Duration::from_secs(23 * 60);
{
let &(ref lock, ref cvar) = &*self.state.clone();
let mut state = lock.lock().unwrap();
// if we are in the inbox (job) thread we only want to wait
// until the next job is due.
if self.folder_config_name == "configured_inbox_folder" {
timeout = get_next_wakeup_time(context, Thread::Imap);
if timeout <= Duration::from_millis(20) {
info!(
context,
"INBOX-IDLE will not be started because of waiting jobs."
);
return;
}
if state.jobs_needed {
info!(
context,
"{}-IDLE will not be started as it was interrupted while not ideling.",
self.name,
);
state.jobs_needed = false;
return;
}
if state.suspended {
@@ -174,8 +171,6 @@ impl JobThread {
}
}
let until = SystemTime::now() + timeout;
let prefix = format!("{}-IDLE", self.name);
let do_fake_idle = match self.imap.connect_configured(context) {
Ok(()) => {
@@ -184,7 +179,7 @@ impl JobThread {
} else {
let watch_folder = self.get_watch_folder(context);
info!(context, "{} started...", prefix);
let res = self.imap.idle(context, watch_folder, until);
let res = self.imap.idle(context, watch_folder);
info!(context, "{} ended...", prefix);
if let Err(err) = res {
warn!(context, "{} failed: {} -> reconnecting", prefix, err);
@@ -204,7 +199,7 @@ impl JobThread {
};
if do_fake_idle {
let watch_folder = self.get_watch_folder(context);
self.imap.fake_idle(context, watch_folder, until);
self.imap.fake_idle(context, watch_folder);
}
self.state.0.lock().unwrap().using_handle = false;

View File

@@ -226,7 +226,7 @@ pub fn send_locations_to_chat(context: &Context, chat_id: u32, seconds: i64) {
context.call_cb(Event::ChatModified(chat_id));
if 0 != seconds {
schedule_MAYBE_SEND_LOCATIONS(context, false);
add_job_with_interrupt(
job_add(
context,
Action::MaybeSendLocationsEnded,
chat_id as i32,
@@ -241,8 +241,7 @@ pub fn send_locations_to_chat(context: &Context, chat_id: u32, seconds: i64) {
#[allow(non_snake_case)]
fn schedule_MAYBE_SEND_LOCATIONS(context: &Context, force_schedule: bool) {
if force_schedule || !job_action_exists(context, Action::MaybeSendLocations) {
// XXX questionable to interrupt but set a +60secs target
add_job_with_interrupt(context, Action::MaybeSendLocations, 0, Params::new(), 60);
job_add(context, Action::MaybeSendLocations, 0, Params::new(), 60);
};
}

View File

@@ -875,7 +875,7 @@ pub fn delete_msgs(context: &Context, msg_ids: &[MsgId]) {
}
}
update_msg_chat_id(context, *msg_id, DC_CHAT_ID_TRASH);
add_job_with_interrupt(
job_add(
context,
Action::DeleteMsgOnImap,
msg_id.to_u32() as i32,
@@ -890,7 +890,7 @@ pub fn delete_msgs(context: &Context, msg_ids: &[MsgId]) {
msg_id: MsgId::new(0),
});
job_kill_action(context, Action::Housekeeping);
add_job_with_interrupt(context, Action::Housekeeping, 0, Params::new(), 10);
job_add(context, Action::Housekeeping, 0, Params::new(), 10);
};
}
@@ -961,7 +961,7 @@ pub fn markseen_msgs(context: &Context, msg_ids: &[MsgId]) -> bool {
update_msg_state(context, *id, MessageState::InSeen);
info!(context, "Seen message {}.", id);
add_job_with_interrupt(
job_add(
context,
Action::MarkseenMsgOnImap,
id.to_u32() as i32,
@@ -1319,7 +1319,7 @@ pub fn update_server_uid(
#[allow(dead_code)]
pub fn dc_empty_server(context: &Context, flags: u32) {
job_kill_action(context, Action::EmptyServer);
add_job_with_interrupt(context, Action::EmptyServer, flags as i32, Params::new(), 0);
job_add(context, Action::EmptyServer, flags as i32, Params::new(), 0);
}
#[cfg(test)]

View File

@@ -15,7 +15,7 @@ use crate::dc_tools::*;
use crate::e2ee;
use crate::error::Result;
use crate::headerdef::HeaderDef;
use crate::job::{add_job_no_interrupt, Action};
use crate::job::{job_add, Action};
use crate::location;
use crate::message;
use crate::message::MsgId;
@@ -782,7 +782,7 @@ impl<'a> MimeParser<'a> {
if self.has_chat_version() && self.context.get_config_bool(Config::MvboxMove) {
param.set_int(Param::AlsoMove, 1);
}
add_job_no_interrupt(self.context, Action::MarkseenMdnOnImap, 0, param, 0);
job_add(self.context, Action::MarkseenMdnOnImap, 0, param, 0);
}
}
}