Moved initial lprofile loading to it's own function.

This commit is contained in:
Filipe Rodrigues 2022-02-14 18:07:16 +00:00
parent 843a8b0d6f
commit e5f0e98c50
4 changed files with 60 additions and 32 deletions

1
Cargo.lock generated
View File

@ -2321,6 +2321,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"async-lock",
"log",
"parking_lot",
"serde",
"zsw-panels",

View File

@ -22,5 +22,8 @@ serde = {version = "1.0.132", features = ["derive"]}
# Error handling
anyhow = "1.0.52"
# Logging
log = "0.4.14"
# Threads
parking_lot = {version = "0.11.2", features = ["deadlock_detection"]}

View File

@ -94,6 +94,51 @@ impl Profiles {
ProfilesLock::new(guard, &self.lock_source)
}
/// Runs the initial profile loader and applier
///
/// # Lock
/// [`ProfilesLock`]
/// [`zsw_playlist::PlaylistLock`]
/// - [`zsw_panels::PanelsLock`]
#[side_effect(MightLock<(ProfilesLock<'profiles>, zsw_playlist::PlaylistLock<'playlist>, zsw_panels::PanelsLock<'panels>)>)]
pub async fn run_loader_applier<'profiles, 'playlist, 'panels>(
&'profiles self,
path: &Path,
playlist: &'playlist Playlist,
panels: &'panels Panels,
) {
// Try to load the profile
// DEADLOCK: Caller ensures we can lock it
let res = {
let mut profiles_lock = self.lock_profiles().await.allow::<MightLock<ProfilesLock>>();
self.load(&mut profiles_lock, path.to_path_buf())
};
// Then check if we got it
match res {
// If we did, apply it
// DEADLOCK: Caller ensures we can lock both in this order
Ok(profile) => {
log::info!("Successfully loaded profile: {profile:?}");
// Lock
let mut playlist_lock = playlist
.lock_playlist()
.await
.allow::<MightLock<zsw_playlist::PlaylistLock>>();
let mut panels_lock = panels.lock_panels().await.allow::<MightLock<zsw_panels::PanelsLock>>();
// Then apply
profile
.apply(playlist, panels, &mut playlist_lock, &mut panels_lock)
.await;
},
Err(err) => log::warn!("Unable to load profile: {err:?}"),
}
}
/// Loads a profile
pub fn load(&self, profiles_lock: &mut ProfilesLock, path: PathBuf) -> Result<Profile, anyhow::Error> {
// Try to load it

View File

@ -95,42 +95,21 @@ pub fn run(args: &Args) -> Result<(), anyhow::Error> {
let mut thread_spawner = zsw_util::ThreadSpawner::new(s);
// Spawn the profile loader if we have any
// TODO: Move to it's own function
if let Some(path) = &args.profile {
// Note: We don't care whether we got cancelled or returned successfully
// DEADLOCK: See above
thread_spawner.spawn("Profile loader", || {
profile_loader_runner
.run(async {
// DEADLOCK: See above
let res = {
let mut profiles_lock = profiles
.lock_profiles()
.await
.allow::<MightLock<zsw_profiles::ProfilesLock>>();
profiles.load(&mut profiles_lock, path.clone())
};
match res {
Ok(profile) => {
log::info!("Successfully loaded profile: {profile:?}");
// DEADLOCK: See above
let mut playlist_lock = playlist
.lock_playlist()
.await
.allow::<MightLock<zsw_playlist::PlaylistLock>>();
// DEADLOCK: See above
let mut panels_lock =
panels.lock_panels().await.allow::<MightLock<zsw_panels::PanelsLock>>();
profile
.apply(&playlist, &panels, &mut playlist_lock, &mut panels_lock)
.await;
},
Err(err) => log::warn!("Unable to load profile: {err:?}"),
}
})
.run(profiles.run_loader_applier(path, &playlist, &panels))
.map(
WithSideEffect::allow::<
MightLock<(
zsw_profiles::ProfilesLock,
zsw_playlist::PlaylistLock,
zsw_panels::PanelsLock,
)>,
>,
)
.into_ok_or_err();
})?;
}