diff --git a/examples/simple.rs b/examples/simple.rs index 5d892dd73..dbb0fdf27 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -1,7 +1,7 @@ extern crate deltachat; use std::ffi::{CStr, CString}; -use std::sync::Arc; +use std::sync::{Arc, RwLock}; use std::{thread, time}; use tempfile::tempdir; @@ -57,6 +57,7 @@ extern "C" fn cb(_ctx: &dc_context_t, event: Event, data1: usize, data2: usize) fn main() { unsafe { let ctx = dc_context_new(cb, std::ptr::null_mut(), std::ptr::null_mut()); + let running = Arc::new(RwLock::new(true)); let info = dc_get_info(&ctx); let info_s = CStr::from_ptr(info); let duration = time::Duration::from_millis(4000); @@ -64,16 +65,29 @@ fn main() { let ctx = Arc::new(ctx); let ctx1 = ctx.clone(); - let t1 = thread::spawn(move || loop { - dc_perform_imap_jobs(&ctx1); - dc_perform_imap_fetch(&ctx1); - dc_perform_imap_idle(&ctx1); + let r1 = running.clone(); + let t1 = thread::spawn(move || { + while *r1.read().unwrap() { + dc_perform_imap_jobs(&ctx1); + if *r1.read().unwrap() { + dc_perform_imap_fetch(&ctx1); + + if *r1.read().unwrap() { + dc_perform_imap_idle(&ctx1); + } + } + } }); let ctx1 = ctx.clone(); - let t2 = thread::spawn(move || loop { - dc_perform_smtp_jobs(&ctx1); - dc_perform_smtp_idle(&ctx1); + let r1 = running.clone(); + let t2 = thread::spawn(move || { + while *r1.read().unwrap() { + dc_perform_smtp_jobs(&ctx1); + if *r1.read().unwrap() { + dc_perform_smtp_idle(&ctx1); + } + } }); let dir = tempdir().unwrap(); @@ -129,6 +143,8 @@ fn main() { } dc_chatlist_unref(chats); + *running.clone().write().unwrap() = false; + println!("stopping threads"); // let msglist = dc_get_chat_msgs(&ctx, chat_id, 0, 0); // for i in 0..dc_array_get_cnt(msglist) { // let msg_id = dc_array_get_id(msglist, i); @@ -139,7 +155,14 @@ fn main() { // } // dc_array_unref(msglist); + deltachat::dc_job::dc_interrupt_imap_idle(&ctx); + deltachat::dc_job::dc_interrupt_smtp_idle(&ctx); + + println!("joining"); t1.join().unwrap(); t2.join().unwrap(); + + println!("closing"); + dc_close(&ctx); } } diff --git a/src/dc_configure.rs b/src/dc_configure.rs index 1844e23c0..a3d0b93bf 100644 --- a/src/dc_configure.rs +++ b/src/dc_configure.rs @@ -137,13 +137,13 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &dc_context_t, _job: *mut context.inbox.read().unwrap().disconnect(context); context .sentbox_thread - .lock() + .read() .unwrap() .imap .disconnect(context); context .mvbox_thread - .lock() + .read() .unwrap() .imap .disconnect(context); diff --git a/src/dc_context.rs b/src/dc_context.rs index c1a537762..21b06a684 100644 --- a/src/dc_context.rs +++ b/src/dc_context.rs @@ -31,8 +31,8 @@ pub struct dc_context_t { pub inbox: Arc>, pub perform_inbox_jobs_needed: Arc>, pub probe_imap_network: Arc>, - pub sentbox_thread: Arc>, - pub mvbox_thread: Arc>, + pub sentbox_thread: Arc>, + pub mvbox_thread: Arc>, pub smtp: Arc>, pub smtp_state: Arc<(Mutex, Condvar)>, pub oauth2_critical: Arc>, @@ -150,7 +150,7 @@ pub fn dc_context_new( bob: Arc::new(RwLock::new(Default::default())), last_smeared_timestamp: Arc::new(RwLock::new(0 as time_t)), cmdline_sel_chat_id: Arc::new(RwLock::new(0)), - sentbox_thread: Arc::new(Mutex::new(unsafe { + sentbox_thread: Arc::new(RwLock::new(unsafe { dc_jobthread_init( b"SENTBOX\x00" as *const u8 as *const libc::c_char, b"configured_sentbox_folder\x00" as *const u8 as *const libc::c_char, @@ -162,7 +162,7 @@ pub fn dc_context_new( ), ) })), - mvbox_thread: Arc::new(Mutex::new(unsafe { + mvbox_thread: Arc::new(RwLock::new(unsafe { dc_jobthread_init( b"MVBOX\x00" as *const u8 as *const libc::c_char, b"configured_mvbox_folder\x00" as *const u8 as *const libc::c_char, @@ -282,8 +282,8 @@ pub unsafe fn dc_context_unref(context: &mut dc_context_t) { } dc_sqlite3_unref(context, &mut context.sql.clone().write().unwrap()); - dc_jobthread_exit(&mut context.sentbox_thread.clone().lock().unwrap()); - dc_jobthread_exit(&mut context.mvbox_thread.clone().lock().unwrap()); + dc_jobthread_exit(&mut context.sentbox_thread.clone().write().unwrap()); + dc_jobthread_exit(&mut context.mvbox_thread.clone().write().unwrap()); free(context.os_name as *mut libc::c_void); } @@ -292,13 +292,13 @@ pub unsafe fn dc_close(context: &dc_context_t) { context.inbox.read().unwrap().disconnect(context); context .sentbox_thread - .lock() + .read() .unwrap() .imap .disconnect(context); context .mvbox_thread - .lock() + .read() .unwrap() .imap .disconnect(context); diff --git a/src/dc_job.rs b/src/dc_job.rs index 28c228a25..aafcbd549 100644 --- a/src/dc_job.rs +++ b/src/dc_job.rs @@ -126,16 +126,8 @@ unsafe fn dc_job_perform(context: &dc_context_t, thread: libc::c_int, probe_netw dc_job_kill_action(context, job.action); sqlite3_finalize(select_stmt); select_stmt = 0 as *mut sqlite3_stmt; - dc_jobthread_suspend( - context, - &mut context.sentbox_thread.clone().lock().unwrap(), - 1, - ); - dc_jobthread_suspend( - context, - &mut context.mvbox_thread.clone().lock().unwrap(), - 1, - ); + dc_jobthread_suspend(context, &context.sentbox_thread.clone().read().unwrap(), 1); + dc_jobthread_suspend(context, &context.mvbox_thread.clone().read().unwrap(), 1); dc_suspend_smtp_thread(context, 1i32); } let mut tries: libc::c_int = 0i32; @@ -185,12 +177,12 @@ unsafe fn dc_job_perform(context: &dc_context_t, thread: libc::c_int, probe_netw if 900i32 == job.action || 910i32 == job.action { dc_jobthread_suspend( context, - &mut context.sentbox_thread.clone().lock().unwrap(), + &mut context.sentbox_thread.clone().read().unwrap(), 0, ); dc_jobthread_suspend( context, - &mut context.mvbox_thread.clone().lock().unwrap(), + &mut context.mvbox_thread.clone().read().unwrap(), 0, ); dc_suspend_smtp_thread(context, 0i32); @@ -1090,7 +1082,7 @@ pub unsafe fn dc_perform_mvbox_fetch(context: &dc_context_t) { ); dc_jobthread_fetch( context, - &mut context.mvbox_thread.clone().lock().unwrap(), + &mut context.mvbox_thread.clone().write().unwrap(), use_network, ); } @@ -1104,13 +1096,13 @@ pub unsafe fn dc_perform_mvbox_idle(context: &dc_context_t) { ); dc_jobthread_idle( context, - &mut context.mvbox_thread.clone().lock().unwrap(), + &context.mvbox_thread.clone().read().unwrap(), use_network, ); } pub unsafe fn dc_interrupt_mvbox_idle(context: &dc_context_t) { - dc_jobthread_interrupt_idle(context, &mut context.mvbox_thread.clone().lock().unwrap()); + dc_jobthread_interrupt_idle(context, &context.mvbox_thread.clone().read().unwrap()); } pub unsafe fn dc_perform_sentbox_fetch(context: &dc_context_t) { @@ -1122,7 +1114,7 @@ pub unsafe fn dc_perform_sentbox_fetch(context: &dc_context_t) { ); dc_jobthread_fetch( context, - &mut context.sentbox_thread.clone().lock().unwrap(), + &mut context.sentbox_thread.clone().write().unwrap(), use_network, ); } @@ -1136,13 +1128,13 @@ pub unsafe fn dc_perform_sentbox_idle(context: &dc_context_t) { ); dc_jobthread_idle( context, - &mut context.sentbox_thread.clone().lock().unwrap(), + &context.sentbox_thread.clone().read().unwrap(), use_network, ); } pub unsafe fn dc_interrupt_sentbox_idle(context: &dc_context_t) { - dc_jobthread_interrupt_idle(context, &mut context.sentbox_thread.clone().lock().unwrap()); + dc_jobthread_interrupt_idle(context, &context.sentbox_thread.clone().read().unwrap()); } pub unsafe fn dc_perform_smtp_jobs(context: &dc_context_t) { diff --git a/src/dc_jobthread.rs b/src/dc_jobthread.rs index 74f21eefe..42cd573c0 100644 --- a/src/dc_jobthread.rs +++ b/src/dc_jobthread.rs @@ -47,7 +47,7 @@ pub unsafe fn dc_jobthread_exit(jobthread: &mut dc_jobthread_t) { pub unsafe fn dc_jobthread_suspend( context: &dc_context_t, - jobthread: &mut dc_jobthread_t, + jobthread: &dc_jobthread_t, suspend: libc::c_int, ) { if 0 != suspend { @@ -88,7 +88,7 @@ pub unsafe fn dc_jobthread_suspend( pub unsafe extern "C" fn dc_jobthread_interrupt_idle( context: &dc_context_t, - jobthread: &mut dc_jobthread_t, + jobthread: &dc_jobthread_t, ) { { jobthread.state.clone().0.lock().unwrap().jobs_needed = 1; @@ -167,7 +167,7 @@ pub unsafe fn dc_jobthread_fetch( * the typical fetch, idle, interrupt-idle ******************************************************************************/ -unsafe fn connect_to_imap(context: &dc_context_t, jobthread: &mut dc_jobthread_t) -> libc::c_int { +unsafe fn connect_to_imap(context: &dc_context_t, jobthread: &dc_jobthread_t) -> libc::c_int { let mut ret_connected: libc::c_int; let mut mvbox_name: *mut libc::c_char = 0 as *mut libc::c_char; @@ -206,7 +206,7 @@ unsafe fn connect_to_imap(context: &dc_context_t, jobthread: &mut dc_jobthread_t pub unsafe fn dc_jobthread_idle( context: &dc_context_t, - jobthread: &mut dc_jobthread_t, + jobthread: &dc_jobthread_t, use_network: libc::c_int, ) { {