diff --git a/Changelog.md b/Changelog.md index 347548d76..ec0d50ca4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -30,6 +30,7 @@ - 修复 Windows 系统代理设置偶发失败的问题 - 修复 Windows 关机被应用阻止的问题 - 修复 Windows 服务模式下 TUN 使用 system/mixed 堆栈时无法接管流量的问题,防火墙放行规则改为自动添加 +- 修复 Windows 配置中 GEO 规则较多时,首次启动内核失败的问题 **🍎 macOS** diff --git a/src-tauri/src/core/manager/state.rs b/src-tauri/src/core/manager/state.rs index 996e062ef..518c6caa9 100644 --- a/src-tauri/src/core/manager/state.rs +++ b/src-tauri/src/core/manager/state.rs @@ -208,33 +208,10 @@ impl CoreManager { let pid = child.pid(); tracing::Span::current().record("pid", pid); - let readiness = poll_sidecar_readiness(SIDECAR_READINESS_ATTEMPTS, SIDECAR_READINESS_INTERVAL, || async { - tokio::time::timeout(SIDECAR_READINESS_PROBE_TIMEOUT, async { - handle::Handle::mihomo().get_version().await - }) - .await - .context("Mihomo readiness probe timed out")??; - Ok(()) - }) - .await; - if let Err(readiness_error) = readiness { - proxy_control::stop_guard().await; - self.core_stopped(); - return match child.kill() { - Ok(()) => Err(readiness_error), - Err(kill_error) => Err(anyhow::anyhow!( - "{readiness_error:#}; failed to terminate unready sidecar PID {pid}: {kill_error:#}" - )), - }; - } - - #[cfg(target_os = "windows")] - self.set_job_handle(Some(job)); - self.set_running_child_sidecar(child); + // The sidecar has to be drained from the moment it starts. tauri-plugin-shell buffers a + // single event, so an unread channel stalls its reader threads and the core blocks on a + // full stdout pipe before it ever creates the API socket. let core_readiness_generation = self.mark_core_ready(); - self.core_started(RunningMode::Sidecar); - self.restore_selected_nodes().await; - AsyncHandler::spawn(move || async move { while let Some(event) = rx.recv().await { match event { @@ -264,6 +241,32 @@ impl CoreManager { } }); + let readiness = poll_sidecar_readiness(SIDECAR_READINESS_ATTEMPTS, SIDECAR_READINESS_INTERVAL, || async { + tokio::time::timeout(SIDECAR_READINESS_PROBE_TIMEOUT, async { + handle::Handle::mihomo().get_version().await + }) + .await + .context("Mihomo readiness probe timed out")??; + Ok(()) + }) + .await; + if let Err(readiness_error) = readiness { + proxy_control::stop_guard().await; + self.core_stopped(); + return match child.kill() { + Ok(()) => Err(readiness_error), + Err(kill_error) => Err(anyhow::anyhow!( + "{readiness_error:#}; failed to terminate unready sidecar PID {pid}: {kill_error:#}" + )), + }; + } + + #[cfg(target_os = "windows")] + self.set_job_handle(Some(job)); + self.set_running_child_sidecar(child); + self.core_started(RunningMode::Sidecar); + self.restore_selected_nodes().await; + Ok(()) }