refactor: mutex

This commit is contained in:
GyDi 2022-04-19 14:38:59 +08:00 committed by GitHub
parent fac437b8c1
commit 3076fd19c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 105 additions and 99 deletions

1
src-tauri/Cargo.lock generated
View File

@ -489,6 +489,7 @@ dependencies = [
"log4rs",
"nanoid",
"open",
"parking_lot 0.12.0",
"port_scanner",
"reqwest",
"serde",

View File

@ -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" }

View File

@ -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))?;
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<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(())

View File

@ -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<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;
// }

View File

@ -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;

View File

@ -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;