From 3076fd19c175a2f07635f4ed70adb4ac7454acf0 Mon Sep 17 00:00:00 2001
From: GyDi <segydi@foxmail.com>
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<T = ()> = Result<T, String>;
 /// get all profiles from `profiles.yaml`
 #[tauri::command]
 pub fn get_profiles(core: State<'_, Core>) -> CmdResult<Profiles> {
-  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))?;
+
+  drop(profiles);
 
-  log_if_err!(core.activate_enhanced(false, false));
+  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<Vec<String>>, 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<Vec<String>>, core: State<'_, Core>) -
 /// change the profile valid fields
 #[tauri::command]
 pub fn change_profile_valid(valid: Option<Vec<String>>, core: State<Core>) -> 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<Vec<String>>, core: State<Core>) -> 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<String> {
-  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<ClashInfo> {
-  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<SysProxyConfig, String> {
 /// which may not the same as system proxy
 #[tauri::command]
 pub fn get_cur_proxy(core: State<'_, Core>) -> CmdResult<Option<SysProxyConfig>> {
-  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<VergeConfig> {
-  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));
+
+    drop(clash);
+    drop(verge);
 
-    // system tray
-    // verge.config.enable_system_proxy.map(|enable| {
-    //   log_if_err!(app
-    //     .tray_handle()
-    //     .get_item("system_proxy")
-    //     .set_selected(enable));
-    // });
+    // 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<Window>) {
-    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::<core::Core>();
-          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::<core::Core>();
-          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>();
 
   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::<Core>();
-  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<bool>) {
+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;
-- 
GitLab