mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-10-14 21:20:48 +08:00
refactor(backend): downgrade lock (#8135)
* refactor(updater): drop write-only pending_* slots * refactor(notify): fold sequence counter into entries lock * refactor(port): fold startup-core-blocked flag into reason slot * refactor(service): drop redundant provider sync serial lock * refactor(port): store startup block reason in a OnceLock * refactor(core): replace macOS network monitor slot with armed latch
This commit is contained in:
@@ -18,12 +18,7 @@ use clash_verge_logging::{Type, logging};
|
||||
use once_cell::sync::Lazy;
|
||||
use parking_lot::Mutex;
|
||||
use serde_yaml_ng::Value;
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
net::SocketAddr,
|
||||
str::FromStr as _,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
use std::{collections::HashSet, net::SocketAddr, str::FromStr as _};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct MixedPortFallback {
|
||||
@@ -32,8 +27,7 @@ struct MixedPortFallback {
|
||||
}
|
||||
|
||||
static PENDING_FALLBACK_NOTICE: Lazy<Mutex<Option<MixedPortFallback>>> = Lazy::new(|| Mutex::new(None));
|
||||
static STARTUP_CORE_BLOCKED: AtomicBool = AtomicBool::new(false);
|
||||
static STARTUP_CORE_BLOCK_REASON: Lazy<Mutex<Option<String>>> = Lazy::new(|| Mutex::new(None));
|
||||
static STARTUP_CORE_BLOCK_REASON: Mutex<Option<String>> = Mutex::new(None);
|
||||
|
||||
impl Config {
|
||||
pub(crate) async fn resolve_startup_mixed_port() -> Result<bool> {
|
||||
@@ -148,17 +142,12 @@ impl Config {
|
||||
}
|
||||
|
||||
pub(crate) fn block_startup_core(error: &anyhow::Error) {
|
||||
STARTUP_CORE_BLOCKED.store(true, Ordering::Release);
|
||||
*STARTUP_CORE_BLOCK_REASON.lock() = Some(error.to_string());
|
||||
report_fallback_error(error.to_string());
|
||||
}
|
||||
|
||||
pub(crate) fn startup_core_block_reason() -> Option<String> {
|
||||
if STARTUP_CORE_BLOCKED.load(Ordering::Acquire) {
|
||||
STARTUP_CORE_BLOCK_REASON.lock().clone()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
STARTUP_CORE_BLOCK_REASON.lock().clone()
|
||||
}
|
||||
|
||||
pub(crate) fn notify_startup_mixed_port_fallback() {
|
||||
|
||||
@@ -5,11 +5,7 @@ use parking_lot::Mutex;
|
||||
use serde_json::json;
|
||||
use smartstring::alias::String;
|
||||
use std::sync::Arc;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
future::Future,
|
||||
sync::atomic::{AtomicU64, Ordering},
|
||||
};
|
||||
use std::{collections::HashMap, future::Future};
|
||||
use tauri::{AppHandle, Emitter as _, Manager as _, WebviewWindow};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -91,16 +87,23 @@ pub struct PendingFailure {
|
||||
/// Non-destructive pending state, indexed by stable code.
|
||||
#[derive(Debug, Default)]
|
||||
struct FailureTable {
|
||||
entries: Mutex<HashMap<String, PendingFailure>>,
|
||||
sequence: AtomicU64,
|
||||
entries: Mutex<FailureEntries>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct FailureEntries {
|
||||
map: HashMap<String, PendingFailure>,
|
||||
sequence: u64,
|
||||
}
|
||||
|
||||
impl FailureTable {
|
||||
fn record(&self, operation: FailedOperation, code: &str, detail: String) {
|
||||
// Sequence assignment and replacement must share one ordering lock.
|
||||
let mut entries = self.entries.lock();
|
||||
entries.sequence = entries.sequence.wrapping_add(1);
|
||||
// Preserve an unanswered request over a later restore.
|
||||
let operation = entries
|
||||
.map
|
||||
.get(code)
|
||||
.filter(|existing| existing.operation.outranks(operation))
|
||||
.map_or(operation, |existing| existing.operation);
|
||||
@@ -108,13 +111,13 @@ impl FailureTable {
|
||||
code: code.into(),
|
||||
detail,
|
||||
operation,
|
||||
sequence: self.sequence.fetch_add(1, Ordering::AcqRel).wrapping_add(1),
|
||||
sequence: entries.sequence,
|
||||
};
|
||||
entries.insert(code.into(), failure);
|
||||
entries.map.insert(code.into(), failure);
|
||||
}
|
||||
|
||||
fn snapshot(&self) -> Vec<PendingFailure> {
|
||||
let mut failures: Vec<PendingFailure> = self.entries.lock().values().cloned().collect();
|
||||
let mut failures: Vec<PendingFailure> = self.entries.lock().map.values().cloned().collect();
|
||||
failures.sort_by_key(|failure| failure.sequence);
|
||||
failures
|
||||
}
|
||||
@@ -122,17 +125,21 @@ impl FailureTable {
|
||||
/// Return whether a guard failure was retired.
|
||||
fn retire_guard(&self) -> bool {
|
||||
let mut entries = self.entries.lock();
|
||||
let before = entries.len();
|
||||
entries.retain(|_, failure| failure.operation != FailedOperation::SystemProxyGuard);
|
||||
before != entries.len()
|
||||
let before = entries.map.len();
|
||||
entries
|
||||
.map
|
||||
.retain(|_, failure| failure.operation != FailedOperation::SystemProxyGuard);
|
||||
before != entries.map.len()
|
||||
}
|
||||
|
||||
/// Return whether any proxy failure was retired.
|
||||
fn retire_system_proxy(&self, asked: FailedOperation) -> bool {
|
||||
let mut entries = self.entries.lock();
|
||||
let before = entries.len();
|
||||
entries.retain(|_, failure| !failure.operation.retired_by_success_of(asked));
|
||||
before != entries.len()
|
||||
let before = entries.map.len();
|
||||
entries
|
||||
.map
|
||||
.retain(|_, failure| !failure.operation.retired_by_success_of(asked));
|
||||
before != entries.map.len()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +286,7 @@ pub fn record_failure(operation: FailedOperation, code: &str, detail: impl Into<
|
||||
}
|
||||
|
||||
pub fn has_pending_failure(code: &str) -> bool {
|
||||
PENDING_FAILURES.entries.lock().contains_key(code)
|
||||
PENDING_FAILURES.entries.lock().map.contains_key(code)
|
||||
}
|
||||
|
||||
/// Return unresolved failures oldest first without clearing them.
|
||||
|
||||
@@ -1045,7 +1045,8 @@ fn decode_hex(encoded: &str) -> Result<Vec<u8>> {
|
||||
}
|
||||
|
||||
static PROVIDER_SYNC_QUEUED: AtomicBool = AtomicBool::new(false);
|
||||
static PROVIDER_SYNC_SERIAL: Lazy<tokio::sync::Mutex<()>> = Lazy::new(|| tokio::sync::Mutex::new(()));
|
||||
// Serializing the whole read-and-publish pass prevents an older cache from replacing a newer one.
|
||||
static PROVIDER_SYNC_SERIAL: tokio::sync::Mutex<()> = tokio::sync::Mutex::const_new(());
|
||||
static SYNC_TEMP_SEQUENCE: AtomicU64 = AtomicU64::new(0);
|
||||
const RUNTIME_PROVIDER_SYNC_ATTEMPTS: u32 = 4;
|
||||
const CONTENT_COMPARE_CHUNK: usize = 64 * 1024;
|
||||
|
||||
Reference in New Issue
Block a user