summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2026-05-19 10:56:36 +0200
committerDavid Lönnhager <david.l@mullvad.net>2026-05-19 11:01:24 +0200
commit141c2330fe1fbf07e4a6669c7cef9213dfbb7f88 (patch)
tree15b33a8c68d01163ac865a8a8ad6c4ed9288420a
parent89eac6b7708b11bd1c377b0ce6b04668037ed70f (diff)
downloadmullvadvpn-141c2330fe1fbf07e4a6669c7cef9213dfbb7f88.tar.xz
mullvadvpn-141c2330fe1fbf07e4a6669c7cef9213dfbb7f88.zip
Merge branch 'fix-relay-settings-race'test-2026.3-beta1-rc3
-rw-r--r--mullvad-daemon/src/lib.rs10
-rw-r--r--mullvad-daemon/src/settings/mod.rs37
2 files changed, 33 insertions, 14 deletions
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs
index 4569403467..e574eca5e7 100644
--- a/mullvad-daemon/src/lib.rs
+++ b/mullvad-daemon/src/lib.rs
@@ -903,10 +903,10 @@ impl Daemon {
});
let param_gen_relay_settings = parameters_generator.clone();
- settings.register_change_listener(move |settings| {
+ settings.register_change_listener_async(move |settings| {
let settings = settings.clone();
let param_gen = param_gen_relay_settings.clone();
- tokio::spawn(async move { param_gen.set_settings(settings).await });
+ async move { param_gen.set_settings(settings).await }
});
// Register a listener for generic settings changes.
@@ -991,13 +991,13 @@ impl Daemon {
// Notify the relay list updater when new relay IP overrides are available.
let relay_list_updater_handle = relay_list_updater.clone();
- settings.register_change_listener(move |settings| {
+ settings.register_change_listener_async(move |settings| {
// Notify relay selector of changes to the settings/selector config
let mut relay_list_updater = relay_list_updater_handle.clone();
let overrides = settings.relay_overrides.clone();
- tokio::spawn(async move {
+ async move {
relay_list_updater.update_overrides(overrides).await;
- });
+ }
});
#[cfg(not(target_os = "android"))]
diff --git a/mullvad-daemon/src/settings/mod.rs b/mullvad-daemon/src/settings/mod.rs
index 292607795c..1539e61892 100644
--- a/mullvad-daemon/src/settings/mod.rs
+++ b/mullvad-daemon/src/settings/mod.rs
@@ -9,6 +9,7 @@ use std::{
fmt::{self, Display},
ops::Deref,
path::{Path, PathBuf},
+ pin::Pin,
};
use talpid_core::firewall::is_local_address;
use talpid_types::ErrorExt;
@@ -112,11 +113,13 @@ fn handle_custom_list_error(
}
}
+type ChangeListener =
+ Box<dyn FnMut(&Settings) -> Pin<Box<dyn Future<Output = ()> + Send + Sync>> + Send + Sync>;
+
pub struct SettingsPersister {
settings: Settings,
path: PathBuf,
- #[expect(clippy::type_complexity)]
- on_change_listeners: Vec<Box<dyn FnMut(&Settings) + Send + Sync>>,
+ on_change_listeners: Vec<ChangeListener>,
}
pub type MadeChanges = bool;
@@ -167,7 +170,7 @@ impl SettingsPersister {
async fn load_inner<F, R>(load_settings: F) -> LoadSettingsResult
where
F: FnOnce() -> R,
- R: std::future::Future<Output = Result<Settings, Error>>,
+ R: Future<Output = Result<Settings, Error>>,
{
let mut result = match load_settings().await {
Ok(settings) => LoadSettingsResult {
@@ -274,7 +277,7 @@ impl SettingsPersister {
})
.await?;
- self.notify_listeners();
+ self.notify_listeners().await;
Ok(())
}
@@ -383,7 +386,7 @@ impl SettingsPersister {
Self::save_inner(&self.path, &new_settings).await?;
self.settings = new_settings;
- self.notify_listeners();
+ self.notify_listeners().await;
Ok(true)
}
@@ -397,14 +400,30 @@ impl SettingsPersister {
pub fn register_change_listener(
&mut self,
- change_listener: impl Fn(&Settings) + Send + Sync + 'static,
+ mut change_listener: impl FnMut(&Settings) + Send + Sync + 'static,
+ ) {
+ self.on_change_listeners.push(Box::new(move |settings| {
+ change_listener(settings);
+ // lord forgive me
+ Box::pin(async move {})
+ }));
+ }
+
+ pub fn register_change_listener_async<
+ F: FnMut(&Settings) -> Fut + Send + Sync + 'static,
+ Fut: Future<Output = ()> + Send + Sync + 'static,
+ >(
+ &mut self,
+ mut change_listener: F,
) {
- self.on_change_listeners.push(Box::new(change_listener));
+ self.on_change_listeners.push(Box::new(move |settings| {
+ Box::pin(change_listener(settings))
+ }));
}
- fn notify_listeners(&mut self) {
+ async fn notify_listeners(&mut self) {
for listener in &mut self.on_change_listeners {
- listener(&self.settings);
+ listener(&self.settings).await;
}
}
}