Files
triangles_v5/notes
SamiAhmed7777 ff90824247 fix(wallet): prevent exit-hang on Windows from detached Tor/I2P threads (#20)
* fix(wallet): prevent exit-hang on Windows from detached Tor/I2P threads

Embedded Tor and embedded I2P each ran on a background std::thread that was
.detach()'d at startup. The teardown paths (CTorEmbedded::Stop,
CI2PEmbedded::Stop) only flipped a running-flag — they did not signal the
thread to exit, and on Windows there is no signal mechanism in tor_api 0.4.x.

Result on Windows: when the user closed the wallet, Shutdown() completed its
bookkeeping and main() returned 0, but the process could not exit because the
detached thread was still in the Tor event loop / i2pd io_context. End Task
(TerminateProcess) was the only escape; the GUI appeared completely stuck.

Fixes:
- tor_embedded.h/.cpp: keep the Tor thread handle; Stop() now raise(SIGTERM)
  on Linux, then joins the thread with a 5s timeout, then TerminateThread
  (Win) / pthread_cancel + pthread_join (Linux) as a last resort.
- i2p_embedded.h/.cpp: same pattern — capture the bootstrap thread and join
  it in Stop() with a 5s timeout fallback.
- init.cpp Shutdown(): spawn a 30s watchdog thread that calls ExitProcess(1)
  if the graceful teardown takes too long. Belt-and-suspenders against any
  future deadlock in the exit path.
- trianglesgui.cpp closeEvent(): second close attempt while the first
  exit is still running immediately calls ExitProcess(2) / _exit(2).
  User escape hatch when the graceful exit hangs.

All non-consensus (threading/process lifecycle only). Build via CI; not local.

Notes: notes/wallet-close-hang-fix-2026-07-07.md

* fix(i2p): drop leftover .detach() that broke build (lambda now joinable)

* fix(i2p): clean up after .detach() removal (trailing comment, blank line)

* fix(tor): MINGW std::thread is pthread-based, use pthread_cancel/join on MINGW

MINGW std::thread::native_handle_type is unsigned long long (pthread_t
emulation), not HANDLE. Mixing pthread handles with Win32
WaitForSingleObject/TerminateThread fails to compile on MINGW with
'invalid conversion' errors.

Use the same pthread_cancel/pthread_join path on Linux and MINGW; keep
TerminateThread only for MSVC builds where native_handle() returns a
real Win32 HANDLE.

---------

Co-authored-by: krystie <krystie>
2026-07-07 18:56:21 -07:00
..