alacritty: On `wsl.exe --shutdown`, Alacritty doesn't close the window until an event is fired

Unlike #915 and the handful of duplicates that have followed it, this is on Windows. I’m currently running Alacritty 28cf90d1308ecd14d9a5646909f7637ddbf105ff (HEAD~3).

Windows Insider Preview, and Alacritty is running wsl.exe -d arch -u me, where arch is a WSL 2 machine.

When I run wsl.exe --shutdown (“Immediately terminates all running distributions and the WSL 2 lightweight utility virtual machine.”), the program that Alacritty was running is killed off, but the Alacritty window remains around until I press a key, move the mouse or something similar.

This is not applying to normal exits; this WSL shutdown is the primary way of triggering it that I’ve found, though I think I’ve triggered it in other ways before as well.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 22 (22 by maintainers)

Commits related to this issue

Most upvoted comments

I think a workaround could be to somehow share tty::process_should_exit check with pty thread so it just terminates.

I’m new to the code so I’m not sure if that’s the best way, happy to give it a try over the weekend.

I think the main problem is on winit side. Alacritty seems to be setting ControlFlow::Exit correctly but this doesn’t ever get checked by winit because of long queue of User::Wakeup events that Alacritty is sending from pty reader thread.

Currently, the only issue on Alacritty side is, it expects glutin/winit loop to exit before terminating pty reader loop. But the latter keeps spamming event loop with events that prevent winit main loop from terminating.

I’ll see if I can make a small winit only app that reproduces the bug and report it with them.

After debugging with different config settings this seems to be 2 issues on top of each other:

  1. When shell exits on its own or crashes, Alacritty window does not close itself until next Windows event is received. It’s also busy-looping here in pty reader thread. This happens with both ConPTY and WinPTY.

  2. With WinPTY only, in the same scenario, main thread is busy looping in winit main loop. There winuser::PeekMessageW doesn’t block and returns the same event on every iteration. No new events seem to be received by the Window and it has to be terminated from task manager. This only happens on the current master but I could reproduce it on v0.3.3 tag.

Ok, I reproduced the problem on v0.3.3 tag (cc3e4d3d5cb2f658d6faef02e4216b9342451efc) with profiler attached. Here’s the hot path where alacritty seems to be spending most of it’s time while it’s window is sticking around

image

Function Name	Total CPU [unit, %]	Self CPU [unit, %]	Module
 + alacritty.exe (PID: 3944)	11962 (100.00%)	0 (0.00%)	Multiple modules
| + [External Code]	11960 (99.98%)	92 (0.77%)	Multiple modules
|| + std::sys::windows::thread::{{impl}}::new::thread_start	11868 (99.21%)	0 (0.00%)	alacritty.exe
||| + alloc::boxed::{{impl}}::call_once<(),FnOnce<()>>	11868 (99.21%)	0 (0.00%)	alacritty.exe
|||| + core::ops::function::FnOnce::call_once<closure-0,()>	11865 (99.19%)	0 (0.00%)	alacritty.exe
||||| + std::thread::{{impl}}::spawn_unchecked::{{closure}}<closure-0,(alacritty_terminal::event_loop::EventLoop<alacritty_terminal::tty::windows::Pty>, alacritty_terminal::event_loop::State)>	11865 (99.19%)	0 (0.00%)	alacritty.exe
|||||| + std::panic::catch_unwind<std::panic::AssertUnwindSafe<closure-0>,(alacritty_terminal::event_loop::EventLoop<alacritty_terminal::tty::windows::Pty>, alacritty_terminal::event_loop::State)>	11865 (99.19%)	0 (0.00%)	alacritty.exe
||||||| + std::panicking::try<(alacritty_terminal::event_loop::EventLoop<alacritty_terminal::tty::windows::Pty>, alacritty_terminal::event_loop::State),std::panic::AssertUnwindSafe<closure-0>>	11865 (99.19%)	0 (0.00%)	alacritty.exe
|||||||| + panic_unwind::__rust_maybe_catch_panic	11865 (99.19%)	0 (0.00%)	alacritty.exe
||||||||| + std::panicking::try::do_call<std::panic::AssertUnwindSafe<closure-0>,(alacritty_terminal::event_loop::EventLoop<alacritty_terminal::tty::windows::Pty>, alacritty_terminal::event_loop::State)>	11865 (99.19%)	0 (0.00%)	alacritty.exe
|||||||||| + std::panic::{{impl}}::call_once<(alacritty_terminal::event_loop::EventLoop<alacritty_terminal::tty::windows::Pty>, alacritty_terminal::event_loop::State),closure-0>	11865 (99.19%)	0 (0.00%)	alacritty.exe
||||||||||| + std::thread::{{impl}}::spawn_unchecked::{{closure}}::{{closure}}<closure-0,(alacritty_terminal::event_loop::EventLoop<alacritty_terminal::tty::windows::Pty>, alacritty_terminal::event_loop::State)>	11865 (99.19%)	0 (0.00%)	alacritty.exe
|||||||||||| + std::sys_common::backtrace::__rust_begin_short_backtrace<closure-0,(alacritty_terminal::event_loop::EventLoop<alacritty_terminal::tty::windows::Pty>, alacritty_terminal::event_loop::State)>	11865 (99.19%)	0 (0.00%)	alacritty.exe
||||||||||||| + alacritty_terminal::event_loop::{{impl}}::spawn::{{closure}}<alacritty_terminal::tty::windows::Pty>	11865 (99.19%)	71 (0.59%)	alacritty.exe
|||||||||||||| - alacritty_terminal::event_loop::EventLoop<alacritty_terminal::tty::windows::Pty>::pty_read<alacritty_terminal::tty::windows::Pty,std::fs::File>	4402 (36.80%)	41 (0.34%)	alacritty.exe
|||||||||||||| - mio::poll::Poll::poll	4257 (35.59%)	4 (0.03%)	alacritty.exe
|||||||||||||| + alacritty_terminal::tty::windows::{{impl}}::reregister	2721 (22.75%)	35 (0.29%)	alacritty.exe
||||||||||||||| - mio::poll::Poll::reregister<alacritty_terminal::tty::windows::EventedReadablePipe>	1436 (12.00%)	23 (0.19%)	alacritty.exe
||||||||||||||| + mio::poll::Poll::reregister<alacritty_terminal::tty::windows::EventedWritablePipe>	1145 (9.57%)	27 (0.23%)	alacritty.exe
|||||||||||||||| - alacritty_terminal::tty::windows::{{impl}}::reregister	1065 (8.90%)	18 (0.15%)	alacritty.exe

@chrisduerr: Just tested the same thing on 9e0b9d5de1b8fe2d9d8ed80f73b4ad0fda171f22 debug build with both

  • nightly-x86_64-pc-windows-msvc unchanged - rustc 1.40.0-nightly (7979016af 2019-10-20)
  • stable-x86_64-pc-windows-msvc unchanged - rustc 1.38.0 (625451e37 2019-09-23)

App seems to be going into a live-lock where it consumes just below 2 CPU cores and never exits also stops reacting to Windows events and redrawing. Persistent logging or increasing verbosity have no effect on that. I guess that’s a separate issue.