From 3076fd19c175a2f07635f4ed70adb4ac7454acf0 Mon Sep 17 00:00:00 2001 From: GyDi Date: Tue, 19 Apr 2022 14:38:59 +0800 Subject: [PATCH] refactor: mutex --- src-tauri/Cargo.lock | 1 + src-tauri/Cargo.toml | 1 + src-tauri/src/cmds.rs | 90 ++++++++++++++++------------------ src-tauri/src/core/mod.rs | 89 ++++++++++++++++++++------------- src-tauri/src/main.rs | 4 +- src-tauri/src/utils/resolve.rs | 19 ++----- 6 files changed, 105 insertions(+), 99 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 7bed2ff..d123d20 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -489,6 +489,7 @@ dependencies = [ "log4rs", "nanoid", "open", + "parking_lot 0.12.0", "port_scanner", "reqwest", "serde", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 0afe654..b1b03ff 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -22,6 +22,7 @@ chrono = "0.4.19" serde_json = "1.0" serde_yaml = "0.8" delay_timer = "0.11.1" +parking_lot = "0.12.0" serde = { version = "1.0", features = ["derive"] } tauri = { version = "1.0.0-rc.6", features = ["process-all", "shell-all", "system-tray", "updater", "window-all"] } window-shadows = { git = "https://github.com/tauri-apps/window-shadows" } diff --git a/src-tauri/src/cmds.rs b/src-tauri/src/cmds.rs index d2d146f..4d1e7a8 100644 --- a/src-tauri/src/cmds.rs +++ b/src-tauri/src/cmds.rs @@ -13,14 +13,14 @@ type CmdResult = Result; /// get all profiles from `profiles.yaml` #[tauri::command] pub fn get_profiles(core: State<'_, Core>) -> CmdResult { - let profiles = core.profiles.lock().unwrap(); + let profiles = core.profiles.lock(); Ok(profiles.clone()) } /// synchronize data irregularly #[tauri::command] pub fn sync_profiles(core: State<'_, Core>) -> CmdResult { - let mut profiles = core.profiles.lock().unwrap(); + let mut profiles = core.profiles.lock(); wrap_err!(profiles.sync_file()) } @@ -34,7 +34,7 @@ pub async fn import_profile( ) -> CmdResult { let item = wrap_err!(PrfItem::from_url(&url, None, None, option).await)?; - let mut profiles = core.profiles.lock().unwrap(); + let mut profiles = core.profiles.lock(); wrap_err!(profiles.append_item(item)) } @@ -49,7 +49,7 @@ pub async fn create_profile( ) -> CmdResult { let item = wrap_err!(PrfItem::from(item, file_data).await)?; - let mut profiles = core.profiles.lock().unwrap(); + let mut profiles = core.profiles.lock(); wrap_err!(profiles.append_item(item)) } @@ -62,7 +62,7 @@ pub async fn update_profile( ) -> CmdResult { let (url, opt) = { // must release the lock here - let profiles = core.profiles.lock().unwrap(); + let profiles = core.profiles.lock(); let item = wrap_err!(profiles.get_item(&index))?; // check the profile type @@ -82,12 +82,13 @@ pub async fn update_profile( let fetch_opt = PrfOption::merge(opt, option); let item = wrap_err!(PrfItem::from_url(&url, None, None, fetch_opt).await)?; - let mut profiles = core.profiles.lock().unwrap(); + let mut profiles = core.profiles.lock(); wrap_err!(profiles.update_item(index.clone(), item))?; // reactivate the profile if Some(index) == profiles.get_current() { - log_if_err!(core.activate_enhanced(false, false)); + drop(profiles); + log_if_err!(core.activate_enhanced(false)); } Ok(()) @@ -96,12 +97,12 @@ pub async fn update_profile( /// change the current profile #[tauri::command] pub fn select_profile(index: String, core: State<'_, Core>) -> CmdResult { - { - let mut profiles = core.profiles.lock().unwrap(); - wrap_err!(profiles.put_current(index))?; - } + let mut profiles = core.profiles.lock(); + wrap_err!(profiles.put_current(index))?; - log_if_err!(core.activate_enhanced(false, false)); + drop(profiles); + + log_if_err!(core.activate_enhanced(false)); Ok(()) } @@ -109,12 +110,13 @@ pub fn select_profile(index: String, core: State<'_, Core>) -> CmdResult { /// change the profile chain #[tauri::command] pub fn change_profile_chain(chain: Option>, core: State<'_, Core>) -> CmdResult { - { - let mut profiles = core.profiles.lock().unwrap(); - profiles.put_chain(chain); - } + dbg!("change profile chain"); + let mut profiles = core.profiles.lock(); + profiles.put_chain(chain); + dbg!("change profile chain finish"); + drop(profiles); - log_if_err!(core.activate_enhanced(false, false)); + log_if_err!(core.activate_enhanced(false)); Ok(()) } @@ -122,10 +124,11 @@ pub fn change_profile_chain(chain: Option>, core: State<'_, Core>) - /// change the profile valid fields #[tauri::command] pub fn change_profile_valid(valid: Option>, core: State) -> CmdResult { - let mut profiles = core.profiles.lock().unwrap(); + let mut profiles = core.profiles.lock(); profiles.put_valid(valid); + drop(profiles); - log_if_err!(core.activate_enhanced(false, false)); + log_if_err!(core.activate_enhanced(false)); Ok(()) } @@ -133,17 +136,19 @@ pub fn change_profile_valid(valid: Option>, core: State) -> Cm /// manually exec enhanced profile #[tauri::command] pub fn enhance_profiles(core: State<'_, Core>) -> CmdResult { - log_if_err!(core.activate_enhanced(false, false)); + log_if_err!(core.activate_enhanced(false)); Ok(()) } /// delete profile item #[tauri::command] pub fn delete_profile(index: String, core: State<'_, Core>) -> CmdResult { - let mut profiles = core.profiles.lock().unwrap(); + let mut profiles = core.profiles.lock(); if wrap_err!(profiles.delete_item(index))? { - log_if_err!(core.activate_enhanced(false, false)); + drop(profiles); + // std::mem::drop(profiles); + log_if_err!(core.activate_enhanced(false)); } Ok(()) @@ -152,7 +157,7 @@ pub fn delete_profile(index: String, core: State<'_, Core>) -> CmdResult { /// patch the profile config #[tauri::command] pub fn patch_profile(index: String, profile: PrfItem, core: State<'_, Core>) -> CmdResult { - let mut profiles = core.profiles.lock().unwrap(); + let mut profiles = core.profiles.lock(); wrap_err!(profiles.patch_item(index, profile)) } @@ -160,7 +165,7 @@ pub fn patch_profile(index: String, profile: PrfItem, core: State<'_, Core>) -> /// run vscode command to edit the profile #[tauri::command] pub fn view_profile(index: String, core: State<'_, Core>) -> CmdResult { - let mut profiles = core.profiles.lock().unwrap(); + let profiles = core.profiles.lock(); let item = wrap_err!(profiles.get_item(&index))?; let file = item.file.clone(); @@ -204,7 +209,7 @@ pub fn view_profile(index: String, core: State<'_, Core>) -> CmdResult { /// read the profile item file data #[tauri::command] pub fn read_profile_file(index: String, core: State<'_, Core>) -> CmdResult { - let mut profiles = core.profiles.lock().unwrap(); + let profiles = core.profiles.lock(); let item = wrap_err!(profiles.get_item(&index))?; let data = wrap_err!(item.read_file())?; @@ -223,7 +228,7 @@ pub fn save_profile_file( return Ok(()); } - let mut profiles = core.profiles.lock().unwrap(); + let profiles = core.profiles.lock(); let item = wrap_err!(profiles.get_item(&index))?; wrap_err!(item.save_file(file_data.unwrap())) } @@ -231,22 +236,14 @@ pub fn save_profile_file( /// restart the sidecar #[tauri::command] pub fn restart_sidecar(core: State<'_, Core>) -> CmdResult { - let mut service = core.service.lock().unwrap(); - - wrap_err!(service.restart())?; - - // 更新配置 - - log_if_err!(core.activate_enhanced(false, false)); - - Ok(()) + wrap_err!(core.restart_clash()) } /// get the clash core info from the state /// the caller can also get the infomation by clash's api #[tauri::command] pub fn get_clash_info(core: State<'_, Core>) -> CmdResult { - let clash = core.clash.lock().unwrap(); + let clash = core.clash.lock(); Ok(clash.info.clone()) } @@ -268,14 +265,14 @@ pub fn get_sys_proxy() -> Result { /// which may not the same as system proxy #[tauri::command] pub fn get_cur_proxy(core: State<'_, Core>) -> CmdResult> { - let verge = core.verge.lock().unwrap(); + let verge = core.verge.lock(); Ok(verge.cur_sysproxy.clone()) } /// get the verge config #[tauri::command] pub fn get_verge_config(core: State<'_, Core>) -> CmdResult { - let verge = core.verge.lock().unwrap(); + let verge = core.verge.lock(); let mut config = verge.config.clone(); if config.system_proxy_bypass.is_none() && verge.cur_sysproxy.is_some() { @@ -296,9 +293,14 @@ pub fn patch_verge_config( let tun_mode = payload.enable_tun_mode.clone(); let system_proxy = payload.enable_system_proxy.clone(); - let mut verge = core.verge.lock().unwrap(); + let mut verge = core.verge.lock(); wrap_err!(verge.patch_config(payload))?; + // change system tray + if system_proxy.is_some() || tun_mode.is_some() { + verge.update_systray(&app_handle).unwrap(); + } + // change tun mode if tun_mode.is_some() { #[cfg(target_os = "windows")] @@ -310,14 +312,8 @@ pub fn patch_verge_config( } } - let profiles = core.profiles.lock().unwrap(); - - log_if_err!(core.activate_enhanced(false, false)); - } - - // change system tray - if system_proxy.is_some() || tun_mode.is_some() { - verge.update_systray(&app_handle).unwrap(); + std::mem::drop(verge); + log_if_err!(core.activate_enhanced(false)); } Ok(()) diff --git a/src-tauri/src/core/mod.rs b/src-tauri/src/core/mod.rs index caed860..fb50efe 100644 --- a/src-tauri/src/core/mod.rs +++ b/src-tauri/src/core/mod.rs @@ -2,10 +2,11 @@ use self::notice::Notice; use self::service::Service; use crate::core::enhance::PrfEnhancedResult; use crate::log_if_err; -use crate::utils::{config, dirs, help}; +use crate::utils::help; use anyhow::{bail, Result}; +use parking_lot::Mutex; use serde_yaml::Mapping; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use std::time::Duration; use tauri::Window; use tokio::time::sleep; @@ -53,58 +54,76 @@ impl Core { } } - pub fn init(&self) { - log_if_err!(self.restart_clash()); + pub fn init(&self, app_handle: tauri::AppHandle) { + let mut service = self.service.lock(); + log_if_err!(service.start()); + drop(service); + + log_if_err!(self.activate()); + + let clash = self.clash.lock(); + let mut verge = self.verge.lock(); + + let hide = verge.config.enable_silent_start.clone().unwrap_or(false); + + // silent start + if hide { + let window = self.window.lock(); + window.as_ref().map(|win| { + win.hide().unwrap(); + }); + } - let clash = self.clash.lock().unwrap(); - let mut verge = self.verge.lock().unwrap(); verge.init_sysproxy(clash.info.port.clone()); log_if_err!(verge.init_launch()); + log_if_err!(verge.update_systray(&app_handle)); - // system tray - // verge.config.enable_system_proxy.map(|enable| { - // log_if_err!(app - // .tray_handle() - // .get_item("system_proxy") - // .set_selected(enable)); - // }); + drop(clash); + drop(verge); + + // wait the window setup during resolve app + let core = self.clone(); + tauri::async_runtime::spawn(async move { + sleep(Duration::from_secs(2)).await; + log_if_err!(core.activate_enhanced(true)); + }); } /// save the window instance pub fn set_win(&self, win: Option) { - let mut window = self.window.lock().unwrap(); + let mut window = self.window.lock(); *window = win; } /// restart the clash sidecar pub fn restart_clash(&self) -> Result<()> { - { - let mut service = self.service.lock().unwrap(); - service.restart()?; - } + let mut service = self.service.lock(); + service.restart()?; + drop(service); self.activate()?; - self.activate_enhanced(false, true) + self.activate_enhanced(true) } /// handle the clash config changed pub fn patch_clash(&self, patch: Mapping) -> Result<()> { let (changed, port) = { - let mut clash = self.clash.lock().unwrap(); + let mut clash = self.clash.lock(); (clash.patch_config(patch)?, clash.info.port.clone()) }; // todo: port check if changed { - let mut service = self.service.lock().unwrap(); + let mut service = self.service.lock(); service.restart()?; + drop(service); self.activate()?; - self.activate_enhanced(false, true)?; + self.activate_enhanced(true)?; - let mut verge = self.verge.lock().unwrap(); + let mut verge = self.verge.lock(); verge.init_sysproxy(port); } @@ -115,13 +134,13 @@ impl Core { /// auto activate enhanced profile pub fn activate(&self) -> Result<()> { let data = { - let profiles = self.profiles.lock().unwrap(); + let profiles = self.profiles.lock(); let data = profiles.gen_activate()?; Clash::strict_filter(data) }; let (mut config, info) = { - let clash = self.clash.lock().unwrap(); + let clash = self.clash.lock(); let config = clash.config.clone(); let info = clash.info.clone(); (config, info) @@ -132,23 +151,23 @@ impl Core { } let config = { - let verge = self.verge.lock().unwrap(); + let verge = self.verge.lock(); let tun_mode = verge.config.enable_tun_mode.unwrap_or(false); Clash::_tun_mode(config, tun_mode) }; let notice = { - let window = self.window.lock().unwrap(); + let window = self.window.lock(); Notice::from(window.clone()) }; - let service = self.service.lock().unwrap(); + let service = self.service.lock(); service.set_config(info, config, notice) } /// enhanced profiles mode - pub fn activate_enhanced(&self, delay: bool, skip: bool) -> Result<()> { - let window = self.window.lock().unwrap(); + pub fn activate_enhanced(&self, skip: bool) -> Result<()> { + let window = self.window.lock(); if window.is_none() { bail!("failed to get the main window"); } @@ -158,7 +177,7 @@ impl Core { // generate the payload let payload = { - let profiles = self.profiles.lock().unwrap(); + let profiles = self.profiles.lock(); profiles.gen_enhanced(event_name.clone())? }; @@ -168,16 +187,17 @@ impl Core { return Ok(()); } + drop(window); return self.activate(); } let tun_mode = { - let verge = self.verge.lock().unwrap(); + let verge = self.verge.lock(); verge.config.enable_tun_mode.unwrap_or(false) }; let info = { - let clash = self.clash.lock().unwrap(); + let clash = self.clash.lock(); clash.info.clone() }; @@ -206,7 +226,7 @@ impl Core { let config = Clash::_tun_mode(config, tun_mode); - let service = service.lock().unwrap(); + let service = service.lock(); log_if_err!(service.set_config(info, config, notice)); log::info!("profile enhanced status {}", result.status); @@ -215,7 +235,6 @@ impl Core { result.error.map(|err| log::error!("{err}")); }); - // wait the window setup during resolve app // if delay { // sleep(Duration::from_secs(2)).await; // } diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 52790e7..97b777e 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -51,7 +51,7 @@ fn main() -> std::io::Result<()> { } "system_proxy" => { let core = app_handle.state::(); - let mut verge = core.verge.lock().unwrap(); + let mut verge = core.verge.lock(); let old_value = verge.config.enable_system_proxy.clone().unwrap_or(false); let new_value = !old_value; @@ -66,7 +66,7 @@ fn main() -> std::io::Result<()> { } "tun_mode" => { let core = app_handle.state::(); - let mut verge = core.verge.lock().unwrap(); + let mut verge = core.verge.lock(); let old_value = verge.config.enable_tun_mode.clone().unwrap_or(false); let new_value = !old_value; diff --git a/src-tauri/src/utils/resolve.rs b/src-tauri/src/utils/resolve.rs index 5678357..0eb69c4 100644 --- a/src-tauri/src/utils/resolve.rs +++ b/src-tauri/src/utils/resolve.rs @@ -1,4 +1,3 @@ -use crate::log_if_err; use crate::{core::Core, utils::init, utils::server}; use tauri::{App, AppHandle, Manager}; @@ -14,33 +13,23 @@ pub fn resolve_setup(app: &App) { let core = app.state::(); core.set_win(app.get_window("main")); - core.init(); + core.init(app.app_handle()); - // clash.set_window(app.get_window("main")); - // log_if_err!(clash.run_sidecar(&profiles, true)); - - resolve_window(app, None); + resolve_window(app); } /// reset system proxy pub fn resolve_reset(app_handle: &AppHandle) { let core = app_handle.state::(); - let mut verge = core.verge.lock().unwrap(); + let mut verge = core.verge.lock(); verge.reset_sysproxy(); } /// customize the window theme -fn resolve_window(app: &App, hide: Option) { +fn resolve_window(app: &App) { let window = app.get_window("main").unwrap(); - // silent start - hide.map(|hide| { - if hide { - window.hide().unwrap(); - } - }); - #[cfg(target_os = "windows")] { use window_shadows::set_shadow;