Fix shutdown race conditions causing bad_weak_ptr crash (v5.4.1)
Build All Platforms / test-linux-unit (push) Waiting to run
Build All Platforms / build-windows-qt (push) Waiting to run
Build All Platforms / build-windows-daemon (push) Waiting to run
Build All Platforms / build-linux-qt (push) Waiting to run
Build All Platforms / build-linux-daemon (push) Waiting to run
Build All Platforms / build-macos (push) Waiting to run
Build All Platforms / release (push) Blocked by required conditions

Fixes multiple concurrency bugs exposed during shutdown when Tor proxy
connections are failing:

- Reorder shutdown: stop network threads before destroying Tor V3 services
- Make RPC listener responsive to fShutdown (poll_one+sleep vs blocking run_one)
- Wrap StopRequests() in try/catch and drain io_service on exit
- Fix leaked CNode AddRef in ThreadSocketHandler2 and ThreadMessageHandler2
  (return→break so Release loop executes)
- Guard vNodes.size() read with cs_vNodes lock (data race)
- Guard Qt UI signal callbacks with fShutdown check (use-after-free)
- Add cs_vNodes lock in CNetCleanup global destructor
- Force-disconnect remaining nodes in StopNode() after threads stop
- Make Tor maintenance thread sleep in 500ms intervals for prompt shutdown

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-27 21:57:34 -07:00
parent b6013edbe4
commit dfb4b221dd
6 changed files with 66 additions and 18 deletions
+5 -2
View File
@@ -2206,7 +2206,9 @@ void ThreadTorMaintenance(void* parg)
while (!fShutdown)
{
MilliSleep(30000); // check every 30 seconds
// Sleep in short intervals so the thread exits promptly on shutdown
for (int i = 0; i < 60 && !fShutdown; i++)
MilliSleep(500);
if (fShutdown) break;
// --- Tor health check & auto-restart ---
@@ -2243,7 +2245,8 @@ void ThreadTorMaintenance(void* parg)
else
{
printf("WARNING: Tor restart failed, retrying in %d seconds\n", restartBackoffSec);
MilliSleep(restartBackoffSec * 1000);
for (int i = 0; i < restartBackoffSec * 2 && !fShutdown; i++)
MilliSleep(500);
if (restartBackoffSec < 300)
restartBackoffSec *= 2;
}