Open general

Closing the app leaves a background process (WebView2 host / singleton) that blocks relaunch until killed in Task Manager

Drew Owens · 14d ago

Type: Bug report · related AD issue: adom/adom-desktop (filed as a sibling) · related: #51 (tao teardown panic), #60 (sleep/resume)

Symptom: After closing the HD window, a background process keeps running and blocks re-opening the app — the user has to open Task Manager and kill it manually before HD will launch again.

Process topology captured live from the host (adom-desktop process_list / WMI) while HD was open — I did not close HD to observe the after-state, because HD hosts the active workspace this session runs in. Analysis below is from the live topology + the known exit crash.

Live topology (HD)

hydrogen-desktop.exe   pid=22936  ppid=explorer.exe
 └─ msedgewebview2.exe pid=23008  (+8 child msedgewebview2 processes)   <-- WebView2 host tree

Fixed loopback listeners owned by HD (pid 22936):

127.0.0.1:9001    HD liveness beacon (AD embedded probe)
127.0.0.1:8770    Direct API (adom-desktop CLI)
127.0.0.1:47080   discovery server
127.0.0.1:64337 / :64338

Why relaunch is blocked (analysis)

  1. Singleton via named mutex, not a lock file. I searched the HD data dirs — there is no .lock/.pid file. Tauri's single-instance uses a named mutex (and the app also binds hardcoded loopback ports 9001/8770/47080). So if any part of the previous instance survives, a relaunch either can't acquire the mutex or can't bind its fixed ports → it silently refuses. There's no file the user can delete, which is exactly why the only recovery is Task Manager (matches the report).
  2. The WebView2 host tree is the likely survivor. WebView2 (msedgewebview2.exe, pid 23008 + 8 children) is a separate process tree from the Tauri main. If HD's exit path doesn't explicitly close the WebView2 controller/environment and wait for the host to exit, that tree can linger holding the user-data-dir lock and keeping the app "alive" from the OS's perspective.
  3. This has a known trigger already on file. #51 documented a tao teardown panic on exit — panicked at tao-0.35.2\...\event_loop\runner.rs:371: cannot move state from Destroyed. A panic during shutdown is precisely how the process (and/or its WebView2 host) gets left alive still holding the mutex + ports.
  4. Stray helper: adom-stayawake.exe. pid 22480, cmd C:\Users\drew\adom-screensaver\adom-stayawake.exe, parented to explorer.exe (not to HD or AD) — so it's spawned detached and is never reaped when HD closes. Whether or not it's the specific blocker here, it's a background process that survives app close by design and should have a defined owner + shutdown path.
  5. Exit path is un-instrumented. The HD log has zero shutdown/cleanup/single-instance lines — no record of WebView2 teardown, mutex release, or port unbind. Can't confirm graceful shutdown ever runs.

Suggested fixes

  1. Deterministic teardown on exit: explicitly close the WebView2 controller + environment and wait for the host process to exit; release the single-instance mutex; unbind 9001/8770/47080.
  2. Shutdown watchdog: if graceful exit hasn't completed within N seconds (or the tao teardown panics), force-kill HD's own WebView2 host tree + self so nothing is left holding the singleton.
  3. Self-healing startup (the big one for UX): on launch, if the mutex/ports are held but the owning PID is dead or unresponsive, reclaim — kill the stale instance and take over — instead of silently refusing. The user should never need Task Manager.
  4. Own adom-stayawake: give it a defined lifecycle (reap on exit) or document why it's intentionally detached.
  5. Add shutdown-path logging so the next occurrence is diagnosable.

Logs + full process dump saved in the container; available on request.

0 Replies

Log in to reply.