diff --git a/src/config.rs b/src/config.rs index 7113c05d0..31390ce9c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,7 @@ //! # Key-value configuration management. +use std::sync::atomic; + use anyhow::{ensure, Context as _, Result}; use strum::{EnumProperty, IntoEnumIterator}; @@ -334,6 +336,8 @@ impl Context { { message::delete_msgs(self, &[MsgId::new(webxdc_message_id)]).await?; } + self.sql.set_raw_config(key, value).await?; + self.debug_logging.store(0, atomic::Ordering::Release); } else { let data: &[u8] = include_bytes!("../assets/webxdc_logging.xdc"); @@ -347,6 +351,8 @@ impl Context { self.sql .set_raw_config(key, Some(&msg_id.to_u32().to_string())) .await?; + self.debug_logging + .store(msg_id.to_u32(), atomic::Ordering::Release); } } _ => { diff --git a/src/context.rs b/src/context.rs index b16381731..af21ab2c8 100644 --- a/src/context.rs +++ b/src/context.rs @@ -6,6 +6,7 @@ use std::ops::Deref; use std::path::{Path, PathBuf}; use std::sync::Arc; use std::time::{Duration, Instant, SystemTime}; +use std::sync::atomic::{self, AtomicU32}; use anyhow::{ensure, Result}; use async_channel::{self as channel, Receiver, Sender}; @@ -231,7 +232,9 @@ pub struct InnerContext { /// The text of the last error logged and emitted as an event. /// If the ui wants to display an error after a failure, /// `last_error` should be used to avoid races with the event thread. - pub(crate) last_error: std::sync::RwLock, + pub(crate) last_error: RwLock, + + pub(crate) debug_logging: AtomicU32, } /// The state of ongoing process. @@ -361,7 +364,8 @@ impl Context { server_id: RwLock::new(None), creation_time: std::time::SystemTime::now(), last_full_folder_scan: Mutex::new(None), - last_error: std::sync::RwLock::new("".to_string()), + last_error: RwLock::new("".to_string()), + debug_logging: AtomicU32::default(), }; let ctx = Context { @@ -437,47 +441,44 @@ impl Context { id: self.id, typ: event.clone(), }); + let context = self.clone(); - async_std::task::spawn(async move { - // TODO synchronously is prob. better - match context.get_config_int(Config::DebugLogging).await { - Err(_) => {} // Probably the database is simply closed (i.e. encrypted and no passphrase available yet) - Ok(0) => {} - Ok(debug_logging_webxdc) => { - let time = SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap_or_default() - .as_millis() as i64; + let debug_logging = context.debug_logging.load(atomic::Ordering::Acquire); + if debug_logging > 0 { + let time = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap_or_default() + .as_millis() as i64; - let webxdc_instance_id = MsgId::new(debug_logging_webxdc as u32); + async_std::task::block_on(async move { + let webxdc_instance_id = MsgId::new(debug_logging as u32); - match context - .internal_write_status_update( - &webxdc_instance_id, - StatusUpdateItem { - payload: event.to_json(Some(time)), - info: None, - summary: None, + match context + .internal_write_status_update( + &webxdc_instance_id, + StatusUpdateItem { + payload: event.to_json(Some(time)), + info: None, + summary: None, + }, + ) + .await + { + Err(err) => { + eprintln!("Can't log event to webxdc status update: {:#}", err); + } + Ok(serial) => { + context.events.emit(Event { + id: context.id, + typ: EventType::WebxdcStatusUpdate { + msg_id: webxdc_instance_id, + status_update_serial: serial, }, - ) - .await - { - Err(err) => { - eprintln!("Can't log event to webxdc status update: {:#}", err); - } - Ok(serial) => { - context.events.emit(Event { - id: context.id, - typ: EventType::WebxdcStatusUpdate { - msg_id: webxdc_instance_id, - status_update_serial: serial, - }, - }); - } + }); } } - } - }); + }); + } } /// Emits a generic MsgsChanged event (without chat or message id) diff --git a/src/message.rs b/src/message.rs index e02201e85..004eb32d6 100644 --- a/src/message.rs +++ b/src/message.rs @@ -2,6 +2,7 @@ use std::collections::BTreeSet; use std::path::{Path, PathBuf}; +use std::sync::atomic; use anyhow::{ensure, format_err, Context as _, Result}; use deltachat_derive::{FromSql, ToSql}; @@ -1287,6 +1288,7 @@ pub async fn delete_msgs(context: &Context, msg_ids: &[MsgId]) -> Result<()> { .sql .set_raw_config(Config::DebugLogging, Some("0")) .await?; + context.debug_logging.store(0, atomic::Ordering::Release); } } diff --git a/src/sql.rs b/src/sql.rs index d9e4ce9e7..6809d2efd 100644 --- a/src/sql.rs +++ b/src/sql.rs @@ -4,6 +4,7 @@ use std::collections::{HashMap, HashSet}; use std::convert::TryFrom; use std::path::Path; use std::path::PathBuf; +use std::sync::atomic; use std::time::Duration; use anyhow::{bail, Context as _, Result}; @@ -341,6 +342,12 @@ impl Sql { } else { info!(context, "Opened database {:?}.", self.dbfile); *self.is_encrypted.write().await = Some(passphrase_nonempty); + + let debug_logging = self.get_raw_config_u32(Config::DebugLogging).await?; + context + .debug_logging + .store(debug_logging.unwrap_or(0), atomic::Ordering::Release); + Ok(()) } }