diff --git a/src/context.rs b/src/context.rs index 144b0ac9b..6f57fc52b 100644 --- a/src/context.rs +++ b/src/context.rs @@ -239,6 +239,9 @@ pub struct InnerContext { pub(crate) oauth2_mutex: Mutex<()>, /// Mutex to prevent a race condition when a "your pw is wrong" warning is sent, resulting in multiple messages being sent. pub(crate) wrong_pw_warning_mutex: Mutex<()>, + /// Mutex to prevent running housekeeping from multiple threads at once. + pub(crate) housekeeping_mutex: Mutex<()>, + pub(crate) translated_stockstrings: StockStrings, pub(crate) events: Events, @@ -478,6 +481,7 @@ impl Context { generating_key_mutex: Mutex::new(()), oauth2_mutex: Mutex::new(()), wrong_pw_warning_mutex: Mutex::new(()), + housekeeping_mutex: Mutex::new(()), translated_stockstrings: stockstrings, events, scheduler: SchedulerState::new(), diff --git a/src/sql.rs b/src/sql.rs index dbd4ffba3..29be64a5d 100644 --- a/src/sql.rs +++ b/src/sql.rs @@ -828,6 +828,10 @@ async fn incremental_vacuum(context: &Context) -> Result<()> { /// Cleanup the account to restore some storage and optimize the database. pub async fn housekeeping(context: &Context) -> Result<()> { + let Ok(_housekeeping_lock) = context.housekeeping_mutex.try_lock() else { + // Housekeeping is already running in another thread, do nothing. + return Ok(()); + }; // Setting `Config::LastHousekeeping` at the beginning avoids endless loops when things do not // work out for whatever reason or are interrupted by the OS. if let Err(e) = context