mirror of
https://github.com/chatmail/core.git
synced 2026-04-20 15:06:30 +03:00
feat: implement minimal rust threads
This commit is contained in:
15
Cargo.lock
generated
15
Cargo.lock
generated
@@ -498,6 +498,19 @@ dependencies = [
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.4.0"
|
||||
@@ -641,6 +654,7 @@ dependencies = [
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"charset 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"debug_stub_derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"deltachat_derive 2.0.0",
|
||||
"email 0.0.21 (git+https://github.com/deltachat/rust-email)",
|
||||
@@ -3346,6 +3360,7 @@ dependencies = [
|
||||
"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
|
||||
"checksum crc24 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fd121741cf3eb82c08dd3023eb55bf2665e5f60ec20f89760cf836ae4562e6a0"
|
||||
"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||
"checksum crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e"
|
||||
"checksum crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c"
|
||||
"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"
|
||||
|
||||
@@ -58,8 +58,8 @@ encoded-words = { git = "https://github.com/async-email/encoded-words", branch="
|
||||
native-tls = "0.2.3"
|
||||
image = { version = "0.22.4", default-features=false, features = ["gif_codec", "jpeg", "ico", "png_codec", "pnm", "webp", "bmp"] }
|
||||
pretty_env_logger = "0.3.1"
|
||||
|
||||
rustyline = { version = "4.1.0", optional = true }
|
||||
crossbeam = "0.7.3"
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3.0"
|
||||
|
||||
@@ -12,7 +12,7 @@ categories = ["cryptography", "std", "email"]
|
||||
|
||||
[lib]
|
||||
name = "deltachat"
|
||||
crate-type = ["cdylib", "staticlib"]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
deltachat = { path = "../", default-features = false }
|
||||
|
||||
@@ -1 +1 @@
|
||||
nightly-2019-11-06
|
||||
nightly-2020-01-26
|
||||
|
||||
103
src/context.rs
103
src/context.rs
@@ -3,7 +3,9 @@
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsString;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc, Condvar, Mutex, RwLock};
|
||||
use std::sync::{Arc, Condvar, Mutex, RwLock, atomic::{Ordering, AtomicBool}};
|
||||
|
||||
use crossbeam::channel::{bounded, unbounded, Receiver, Sender};
|
||||
|
||||
use crate::chat::*;
|
||||
use crate::config::Config;
|
||||
@@ -47,8 +49,6 @@ pub struct Context {
|
||||
pub smtp: Arc<Mutex<Smtp>>,
|
||||
pub smtp_state: Arc<(Mutex<SmtpState>, Condvar)>,
|
||||
pub oauth2_critical: Arc<Mutex<()>>,
|
||||
#[debug_stub = "Callback"]
|
||||
cb: Box<ContextCallback>,
|
||||
pub os_name: Option<String>,
|
||||
pub cmdline_sel_chat_id: Arc<RwLock<ChatId>>,
|
||||
pub bob: Arc<RwLock<BobStatus>>,
|
||||
@@ -57,6 +57,16 @@ pub struct Context {
|
||||
/// Mutex to avoid generating the key for the user more than once.
|
||||
pub generating_key_mutex: Mutex<()>,
|
||||
pub translated_stockstrings: RwLock<HashMap<usize, String>>,
|
||||
|
||||
#[debug_stub = "Callback"]
|
||||
cb: Box<ContextCallback>,
|
||||
|
||||
event_sender: Sender<Event>,
|
||||
event_receiver: Receiver<Event>,
|
||||
shutdown_sender: Sender<()>,
|
||||
shutdown_receiver: Receiver<()>,
|
||||
|
||||
is_running: AtomicBool,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
@@ -80,6 +90,16 @@ pub fn get_info() -> HashMap<&'static str, String> {
|
||||
res
|
||||
}
|
||||
|
||||
macro_rules! while_running {
|
||||
($self:expr, $code:block) => {
|
||||
if $self.is_running.load(Ordering::Relaxed) {
|
||||
$code
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl Context {
|
||||
/// Creates new context.
|
||||
pub fn new(cb: Box<ContextCallback>, os_name: String, dbfile: PathBuf) -> Result<Context> {
|
||||
@@ -106,6 +126,10 @@ impl Context {
|
||||
"Blobdir does not exist: {}",
|
||||
blobdir.display()
|
||||
);
|
||||
|
||||
let (event_sender, event_receiver) = unbounded();
|
||||
let (shutdown_sender, shutdown_receiver) = bounded(0);
|
||||
|
||||
let ctx = Context {
|
||||
blobdir,
|
||||
dbfile,
|
||||
@@ -138,6 +162,11 @@ impl Context {
|
||||
perform_inbox_jobs_needed: Arc::new(RwLock::new(false)),
|
||||
generating_key_mutex: Mutex::new(()),
|
||||
translated_stockstrings: RwLock::new(HashMap::new()),
|
||||
event_sender,
|
||||
event_receiver,
|
||||
shutdown_sender,
|
||||
shutdown_receiver,
|
||||
is_running: Default::default(),
|
||||
};
|
||||
|
||||
ensure!(
|
||||
@@ -159,7 +188,73 @@ impl Context {
|
||||
}
|
||||
|
||||
pub fn call_cb(&self, event: Event) {
|
||||
(*self.cb)(self, event);
|
||||
self.event_sender.send(event).unwrap();
|
||||
}
|
||||
|
||||
/// Start the run loop.
|
||||
pub fn run(&self) {
|
||||
use crossbeam::channel::select;
|
||||
|
||||
self.is_running.store(true, Ordering::Relaxed);
|
||||
|
||||
crossbeam::scope(|s| {
|
||||
let imap_handle = s.spawn(|_| loop {
|
||||
while_running!(self, {
|
||||
perform_inbox_jobs(self);
|
||||
while_running!(self, {
|
||||
perform_inbox_fetch(self);
|
||||
while_running!(self, { perform_inbox_idle(self) });
|
||||
});
|
||||
});
|
||||
});
|
||||
let mvbox_handle = s.spawn(|_| loop {
|
||||
while_running!(self, {
|
||||
perform_mvbox_fetch(self);
|
||||
while_running!(self, {
|
||||
perform_mvbox_idle(self);
|
||||
});
|
||||
});
|
||||
});
|
||||
let sentbox_handle = s.spawn(|_| loop {
|
||||
while_running!(self, {
|
||||
perform_sentbox_fetch(self);
|
||||
while_running!(self, {
|
||||
perform_sentbox_idle(self);
|
||||
});
|
||||
});
|
||||
});
|
||||
let smtp_handle = s.spawn(|_| loop {
|
||||
while_running!(self, {
|
||||
perform_smtp_jobs(self);
|
||||
while_running!(self, {
|
||||
perform_smtp_idle(self);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
loop {
|
||||
select! {
|
||||
recv(self.event_receiver) -> event => {
|
||||
// This gurantees that the callback is always called from the thread
|
||||
// that called `run`.
|
||||
(*self.cb)(self, event.unwrap())
|
||||
},
|
||||
recv(self.shutdown_receiver) -> _ => break,
|
||||
}
|
||||
}
|
||||
|
||||
imap_handle.join().unwrap();
|
||||
mvbox_handle.join().unwrap();
|
||||
sentbox_handle.join().unwrap();
|
||||
smtp_handle.join().unwrap();
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Stop the run loop. Blocks until all threads have shutdown.
|
||||
pub fn shutdown(&self) {
|
||||
self.is_running.store(false, Ordering::Relaxed);
|
||||
self.shutdown_sender.send(()).unwrap();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(clippy::correctness, missing_debug_implementations, clippy::all)]
|
||||
#![allow(clippy::match_bool)]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user