Skip to content

fix(windows): prevent warp.exe from hanging after window closes#10216

Draft
acarl005 wants to merge 2 commits intomasterfrom
oz-agent/fix-windows-process-no-terminate-10202
Draft

fix(windows): prevent warp.exe from hanging after window closes#10216
acarl005 wants to merge 2 commits intomasterfrom
oz-agent/fix-windows-process-no-terminate-10202

Conversation

@acarl005
Copy link
Copy Markdown
Contributor

@acarl005 acarl005 commented May 6, 2026

Description

Fixes the intermittent bug (#10202) where warp.exe stays alive after the window visually closes on Windows.

Root cause

When the user closes Warp, the event loop fires LoopExiting:

  1. Window is hidden (hide_app()) — this is the visual close the user sees
  2. on_will_terminate runs synchronouslystd::process::exit(0) is only called after this returns
  3. On Windows, on_will_terminate calls shutdown_all_pty_event_loops(), which sends Message::Shutdown to each PTY event loop thread and then calls join_handle.join() with no timeout
  4. If a PTY event loop thread fails to exit — due to e.g. a blocking pipe operation in Pty::drop() after conpty_api.close(), or a mio Waker::wake() failure that goes unnoticed — the join blocks forever
  5. on_will_terminate never returns → std::process::exit(0) is never called → process stays alive with no visible window

The intermittency is explained by the race between ConPTY/OpenConsole teardown timing and whether the pipe read in Pty::drop() returns WouldBlock or stalls momentarily.

Fix

terminal_manager.rs: Add a 5-second timeout to shutdown_event_loop on Windows. If a PTY event loop thread doesn't exit within the timeout, log a warning and proceed. std::process::exit(0) will kill the remaining thread. The OS will close the ConPTY handle when the process exits, which signals OpenConsole to exit on its own.

mio_channel.rs: Surface Waker::wake() failures as logged errors instead of silently swallowing them (let _ = waker.wake()). This makes it easier to diagnose whether a Waker failure is causing the event loop to stay blocked in poll.poll().

Linked Issue

Screenshots / Videos

N/A — internal shutdown timing fix.

Testing

The bug is intermittent and Windows-only, which makes it difficult to add a deterministic automated test. The DEV-channel sleep in autoupdate/windows.rs (which simulates a slow shutdown) can be used on a Windows dev machine to verify the process now exits promptly.

Manual test plan:

  • Open Warp on Windows with one or more active terminal sessions
  • Close the window; verify warp.exe disappears from Task Manager promptly
  • Trigger an auto-update; verify the installer completes without hanging

Agent Mode

  • Warp Agent Mode - This PR was created via Warp's AI Agent Mode

This PR was created by Oz (running Claude Code).

When the user closes Warp on Windows, the window hides immediately but
`std::process::exit(0)` is only called after `on_will_terminate` returns.
`shutdown_all_pty_event_loops` (Windows-only) joins PTY event loop threads
with no timeout; if a thread fails to exit the process hangs indefinitely.

Add a 5-second timeout to `shutdown_event_loop` on Windows so that a stuck
PTY event loop thread never prevents the process from exiting. If the timeout
fires, the thread is left to be killed by `std::process::exit(0)`, and the OS
will close the ConPTY handle which signals OpenConsole to exit on its own.

Also surface mio `Waker::wake()` failures as logged errors instead of
silently swallowing them, making it easier to diagnose if wake-up failures
are the root cause of a stuck event loop on a given machine.

Co-Authored-By: Oz <[email protected]>
@cla-bot cla-bot Bot added the cla-signed label May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

warp.exe process does not terminate reliably

1 participant