From ba23ea4f22b5482d036706124a196fa03ef4b521 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 12 Jul 2026 01:27:46 +0900 Subject: fix(proxy-manager): correct singleton lifecycle and simplify to a plain Mutex reset() eagerly rebuilt the ProxyManager singleton immediately, capturing env vars before a caller could set them for the next request. PHP's reset() just nulls the static instance; getInstance() lazily constructs on next use. Match that so proxy env vars set after reset() are observed. get_instance() also ensured the singleton was constructed under its own lock, dropped that lock, and returned the bare Mutex; every caller then took a second, independent lock. A reset() landing in that gap would leave the caller observing None and panicking on .as_ref().unwrap(), a state the old eager-reconstructing reset() could not produce. Return the already-locked MutexGuard from get_instance() instead, so construction and use happen under one lock, and update all call sites accordingly. Holding that guard across a loop body then deadlocked in diagnose_command, since check_http_proxy transitively re-enters get_instance() via HttpDownloader -> CurlDownloader, and std::sync::Mutex is not reentrant. Re-acquire the lock fresh each iteration with a short-lived guard instead. Finally, Mutex::new is a const fn, so the OnceLock wrapper around it was unnecessary indirection; a bare static Mutex> initializes to the same state without the get_or_init/get dance. Co-Authored-By: Claude Sonnet 5 --- crates/shirabe/src/util/http/curl_downloader.rs | 2 -- 1 file changed, 2 deletions(-) (limited to 'crates/shirabe/src/util/http/curl_downloader.rs') diff --git a/crates/shirabe/src/util/http/curl_downloader.rs b/crates/shirabe/src/util/http/curl_downloader.rs index 6a6a1d66..f698fc25 100644 --- a/crates/shirabe/src/util/http/curl_downloader.rs +++ b/crates/shirabe/src/util/http/curl_downloader.rs @@ -222,8 +222,6 @@ impl CurlDownloader { // PHP logs the proxy in the "Downloading" line; resolving it here keeps that message // faithful even though reqwest does not yet apply the proxy (see send_once TODO). let using_proxy = ProxyManager::get_instance() - .lock() - .unwrap() .as_ref() .map(|pm| pm.get_proxy_for_request(url)) .transpose() -- cgit v1.3.1