From ac3afe4dee5aff3ad3901493b4cbfa881019f220 Mon Sep 17 00:00:00 2001 From: Tunglies Date: Sun, 6 Jul 2025 02:14:48 +0800 Subject: [PATCH] fix: manage setup Mutex crash (#3995) * Revert "Revert "refactor: Replace std::sync::Mutex with parking_lot::Mutex for improved performance and consistency in multiple files" (#3990)" This reverts commit 667844aa12658ba835e50677cf399233004dd610. * refactor: Manage lightweight state in the app setup and clean up unused proxy client code * refactor: Move macOS-specific Manager import under conditional compilation --- src-tauri/src/enhance/script.rs | 7 +- src-tauri/src/lib.rs | 17 ++-- src-tauri/src/module/lightweight.rs | 8 +- src-tauri/src/utils/network.rs | 130 +++------------------------- 4 files changed, 27 insertions(+), 135 deletions(-) diff --git a/src-tauri/src/enhance/script.rs b/src-tauri/src/enhance/script.rs index 09ef378d..b36a9214 100644 --- a/src-tauri/src/enhance/script.rs +++ b/src-tauri/src/enhance/script.rs @@ -8,7 +8,8 @@ pub fn use_script( name: String, ) -> Result<(Mapping, Vec<(String, String)>)> { use boa_engine::{native_function::NativeFunction, Context, JsValue, Source}; - use std::sync::{Arc, Mutex}; + use parking_lot::Mutex; + use std::sync::Arc; let mut context = Context::default(); let outputs = Arc::new(Mutex::new(vec![])); @@ -24,7 +25,7 @@ pub fn use_script( let level = level.to_std_string().unwrap(); let data = args.get(1).unwrap().to_string(context)?; let data = data.to_std_string().unwrap(); - let mut out = copy_outputs.lock().unwrap(); + let mut out = copy_outputs.lock(); out.push((level, data)); Ok(JsValue::undefined()) }, @@ -67,7 +68,7 @@ pub fn use_script( // 直接解析JSON结果,不做其他解析 let res: Result = parse_json_safely(&result); - let mut out = outputs.lock().unwrap(); + let mut out = outputs.lock(); match res { Ok(config) => Ok((use_lowercase(config), out.to_vec())), Err(err) => { diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index cd5fa763..b2f8a1dd 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -13,8 +13,10 @@ use crate::{ utils::{resolve, resolve::resolve_scheme, server}, }; use config::Config; -use std::sync::{Mutex, Once}; +use parking_lot::Mutex; +use std::sync::Once; use tauri::AppHandle; +#[cfg(target_os = "macos")] use tauri::Manager; #[cfg(target_os = "macos")] use tauri_plugin_autostart::MacosLauncher; @@ -41,14 +43,14 @@ impl AppHandleManager { /// Initialize the app handle manager with an app handle. pub fn init(&self, handle: AppHandle) { self.init.call_once(|| { - let mut app_handle = self.inner.lock().unwrap(); + let mut app_handle = self.inner.lock(); *app_handle = Some(handle); }); } /// Get the app handle if it has been initialized. pub fn get(&self) -> Option { - self.inner.lock().unwrap().clone() + self.inner.lock().clone() } /// Get the app handle, panics if it hasn't been initialized. @@ -59,7 +61,7 @@ impl AppHandleManager { pub fn set_activation_policy_regular(&self) { #[cfg(target_os = "macos")] { - let app_handle = self.inner.lock().unwrap(); + let app_handle = self.inner.lock(); let app_handle = app_handle.as_ref().unwrap(); let _ = app_handle.set_activation_policy(tauri::ActivationPolicy::Regular); } @@ -68,7 +70,7 @@ impl AppHandleManager { pub fn set_activation_policy_accessory(&self) { #[cfg(target_os = "macos")] { - let app_handle = self.inner.lock().unwrap(); + let app_handle = self.inner.lock(); let app_handle = app_handle.as_ref().unwrap(); let _ = app_handle.set_activation_policy(tauri::ActivationPolicy::Accessory); } @@ -77,7 +79,7 @@ impl AppHandleManager { pub fn set_activation_policy_prohibited(&self) { #[cfg(target_os = "macos")] { - let app_handle = self.inner.lock().unwrap(); + let app_handle = self.inner.lock(); let app_handle = app_handle.as_ref().unwrap(); let _ = app_handle.set_activation_policy(tauri::ActivationPolicy::Prohibited); } @@ -134,6 +136,7 @@ pub fn run() { .plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_deep_link::init()) + .manage(Mutex::new(state::lightweight::LightWeightState::default())) .setup(|app| { logging!(info, Type::Setup, true, "开始应用初始化..."); let mut auto_start_plugin_builder = tauri_plugin_autostart::Builder::new(); @@ -213,8 +216,6 @@ pub fn run() { logging!(error, Type::Setup, true, "初始化资源失败: {}", e); } - app.manage(Mutex::new(state::lightweight::LightWeightState::default())); - logging!(info, Type::Setup, true, "初始化完成,继续执行"); Ok(()) }) diff --git a/src-tauri/src/module/lightweight.rs b/src-tauri/src/module/lightweight.rs index b69c8b1d..ff9ae361 100644 --- a/src-tauri/src/module/lightweight.rs +++ b/src-tauri/src/module/lightweight.rs @@ -13,10 +13,8 @@ use crate::AppHandleManager; use anyhow::{Context, Result}; use delay_timer::prelude::TaskBuilder; -use std::sync::{ - atomic::{AtomicBool, Ordering}, - Mutex, -}; +use parking_lot::Mutex; +use std::sync::atomic::{AtomicBool, Ordering}; use tauri::{Listener, Manager}; const LIGHT_WEIGHT_TASK_UID: &str = "light_weight_task"; @@ -30,7 +28,7 @@ where { let app_handle = handle::Handle::global().app_handle().unwrap(); let state = app_handle.state::>(); - let mut guard = state.lock().unwrap(); + let mut guard = state.lock(); f(&mut guard) } diff --git a/src-tauri/src/utils/network.rs b/src-tauri/src/utils/network.rs index b84289cd..d72284d8 100644 --- a/src-tauri/src/utils/network.rs +++ b/src-tauri/src/utils/network.rs @@ -1,8 +1,9 @@ use anyhow::Result; use lazy_static::lazy_static; +use parking_lot::Mutex; use reqwest::{Client, ClientBuilder, Proxy, RequestBuilder, Response}; use std::{ - sync::{Arc, Mutex, Once}, + sync::{Arc, Once}, time::{Duration, Instant}, }; use tokio::runtime::{Builder, Runtime}; @@ -78,7 +79,7 @@ impl NetworkManager { .build() .expect("Failed to build no_proxy client"); - let mut no_proxy_guard = NETWORK_MANAGER.no_proxy_client.lock().unwrap(); + let mut no_proxy_guard = NETWORK_MANAGER.no_proxy_client.lock(); *no_proxy_guard = Some(no_proxy_client); logging!(info, Type::Network, true, "网络管理器初始化完成"); @@ -87,16 +88,16 @@ impl NetworkManager { } fn record_connection_error(&self, error: &str) { - let mut last_error = self.last_connection_error.lock().unwrap(); + let mut last_error = self.last_connection_error.lock(); *last_error = Some((Instant::now(), error.to_string())); - let mut error_count = self.connection_error_count.lock().unwrap(); + let mut error_count = self.connection_error_count.lock(); *error_count += 1; } fn should_reset_clients(&self) -> bool { - let error_count = *self.connection_error_count.lock().unwrap(); - let last_error = self.last_connection_error.lock().unwrap(); + let error_count = *self.connection_error_count.lock(); + let last_error = self.last_connection_error.lock(); if error_count > 5 { return true; @@ -114,132 +115,23 @@ impl NetworkManager { pub fn reset_clients(&self) { logging!(info, Type::Network, true, "正在重置所有HTTP客户端"); { - let mut client = self.self_proxy_client.lock().unwrap(); + let mut client = self.self_proxy_client.lock(); *client = None; } { - let mut client = self.system_proxy_client.lock().unwrap(); + let mut client = self.system_proxy_client.lock(); *client = None; } { - let mut client = self.no_proxy_client.lock().unwrap(); + let mut client = self.no_proxy_client.lock(); *client = None; } { - let mut error_count = self.connection_error_count.lock().unwrap(); + let mut error_count = self.connection_error_count.lock(); *error_count = 0; } } - /* - /// 获取或创建自代理客户端 - fn get_or_create_self_proxy_client(&self) -> Client { - if self.should_reset_clients() { - self.reset_clients(); - } - let mut client_guard = self.self_proxy_client.lock().unwrap(); - - if client_guard.is_none() { - let port = Config::verge() - .latest_ref() - .verge_mixed_port - .unwrap_or(Config::clash().latest_ref().get_mixed_port()); - - let proxy_scheme = format!("http://127.0.0.1:{port}"); - - let mut builder = ClientBuilder::new() - .use_rustls_tls() - .pool_max_idle_per_host(POOL_MAX_IDLE_PER_HOST) - .pool_idle_timeout(POOL_IDLE_TIMEOUT) - .connect_timeout(DEFAULT_CONNECT_TIMEOUT) - .timeout(DEFAULT_REQUEST_TIMEOUT) - .http2_initial_stream_window_size(H2_STREAM_WINDOW_SIZE) - .http2_initial_connection_window_size(H2_CONNECTION_WINDOW_SIZE) - .http2_adaptive_window(true) - .http2_keep_alive_interval(Some(H2_KEEP_ALIVE_INTERVAL)) - .http2_keep_alive_timeout(H2_KEEP_ALIVE_TIMEOUT) - .http2_max_frame_size(H2_MAX_FRAME_SIZE) - .tcp_keepalive(Some(Duration::from_secs(10))) - .http2_max_header_list_size(16 * 1024); - - if let Ok(proxy) = Proxy::http(&proxy_scheme) { - builder = builder.proxy(proxy); - } - if let Ok(proxy) = Proxy::https(&proxy_scheme) { - builder = builder.proxy(proxy); - } - if let Ok(proxy) = Proxy::all(&proxy_scheme) { - builder = builder.proxy(proxy); - } - - let client = builder.build().expect("Failed to build self_proxy client"); - *client_guard = Some(client); - } - - client_guard.as_ref().unwrap().clone() - } - - /// 获取或创建系统代理客户端 - fn get_or_create_system_proxy_client(&self) -> Client { - if self.should_reset_clients() { - self.reset_clients(); - } - - let mut client_guard = self.system_proxy_client.lock().unwrap(); - - if client_guard.is_none() { - use sysproxy::Sysproxy; - - let mut builder = ClientBuilder::new() - .use_rustls_tls() - .pool_max_idle_per_host(POOL_MAX_IDLE_PER_HOST) - .pool_idle_timeout(POOL_IDLE_TIMEOUT) - .connect_timeout(DEFAULT_CONNECT_TIMEOUT) - .timeout(DEFAULT_REQUEST_TIMEOUT) - .http2_initial_stream_window_size(H2_STREAM_WINDOW_SIZE) - .http2_initial_connection_window_size(H2_CONNECTION_WINDOW_SIZE) - .http2_adaptive_window(true) - .http2_keep_alive_interval(Some(H2_KEEP_ALIVE_INTERVAL)) - .http2_keep_alive_timeout(H2_KEEP_ALIVE_TIMEOUT) - .http2_max_frame_size(H2_MAX_FRAME_SIZE) - .tcp_keepalive(Some(Duration::from_secs(10))) - .http2_max_header_list_size(16 * 1024); - - if let Ok(p @ Sysproxy { enable: true, .. }) = Sysproxy::get_system_proxy() { - let proxy_scheme = format!("http://{}:{}", p.host, p.port); - - if let Ok(proxy) = Proxy::http(&proxy_scheme) { - builder = builder.proxy(proxy); - } - if let Ok(proxy) = Proxy::https(&proxy_scheme) { - builder = builder.proxy(proxy); - } - if let Ok(proxy) = Proxy::all(&proxy_scheme) { - builder = builder.proxy(proxy); - } - } - - let client = builder - .build() - .expect("Failed to build system_proxy client"); - *client_guard = Some(client); - } - - client_guard.as_ref().unwrap().clone() - } - - /// 根据代理设置选择合适的客户端 - pub fn get_client(&self, proxy_type: ProxyType) -> Client { - match proxy_type { - ProxyType::NoProxy => { - let client_guard = self.no_proxy_client.lock().unwrap(); - client_guard.as_ref().unwrap().clone() - } - ProxyType::SelfProxy => self.get_or_create_self_proxy_client(), - ProxyType::SystemProxy => self.get_or_create_system_proxy_client(), - } - } - */ /// 创建带有自定义选项的HTTP请求 pub fn create_request( &self,