-
Notifications
You must be signed in to change notification settings - Fork 8.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ConPTY host lingers when all connected clients have been terminated #4564
Comments
Due to the way that ptys are implemented on NT, the master side read pipe will not receive an EOF when all clients have terminated (since the ConPTY process is still running). We now keep track of the processes and kill the ConPTY when all the processes using the slave side are gone. Note that this is NOT 100% (or even 80%) safe. Indirect processes may still be running, or processes may terminate after we have already entered a blocking read(). A feature request has been registered with the Windows Terminal team (microsoft/terminal#4564).
So, funny enough, this is actually supposed to work properly. The handles servicing the PTY should get EOF when the last connected application goes away. We recently made some changed in this area (can't find the bug/PR right now) that resulted in significantly more regressions than we were comfortable with, but it's definitely on our radar. Thanks! |
Shortest possible version of the explanation: the pty host is holding a ConDrv device reference handle, and conhost thinks there's still a client connected because of it. 😄 |
This seems to me to have the potential for a race condition when starting multiple short-lived processes on the same ConPTY. I guess you could start a long-lived process (eg hanging on a read on a stdin pipe) first, and then the payload processes, and then terminating the first process by closing its stdin. |
As I understand it's not yer resolved, right? But what is the proper way to read all output of a process then? Thank you |
2 new ConPTY APIs were added as part of this commit: * `ClosePseudoConsoleTimeout` Complements `ClosePseudoConsole`, allowing users to override the `INFINITE` wait for OpenConsole to exit with any arbitrary timeout, including 0. * `ConptyReleasePseudoConsole` This releases the `\Reference` handle held by the `HPCON`. While it makes launching further PTY clients via `PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE` impossible, it does allow conhost/OpenConsole to exit naturally once all console clients have disconnected. This makes it unnecessary to having to monitor the exit of the spawned shell/application, just to then call `ClosePseudoConsole`, while carefully continuing to read from the output pipe. Instead users can now just read from the output pipe until it is closed, knowing for sure that no more data will come or clients connect. This is especially useful in combination with `ClosePseudoConsoleTimeout` and a timeout of 0, to allow conhost/OpenConsole to exit asynchronously. These new APIs are used to fix an array of bugs around Windows Terminal exiting either too early or too late. They also make usage of the ConPTY API simpler in most situations (when spawning a single application and waiting for it to exit). Depends on #13882, #14041, #14160, #14282 Closes #4564 Closes #14416 Closes MSFT-42244182 ## Validation Steps Performed * Calling `FreeConsole` in a handoff'd application closes the tab ✅ * Create a .bat file containing only `start /B cmd.exe`. If WT stable is the default terminal the tab closes instantly ✅ With these changes included the tab stays open with a cmd.exe prompt ✅ * New ConPTY tests ✅
🎉This issue was addressed in #14544, which has now been successfully released as Handy links: |
Description of the new feature/enhancement
On POSIX systems the master end will receive an EOF when all processes that use the slave have terminated or closed the connection. With ConPTY this does not appear to happen, as the pty handling process continues running (and could be used to start new processes). Closing the ConPTY will generate an EOF, but also terminate any remaining processes and possibly lose pending output.
Currently a master that does a blocking read from a ConPTY pipe will hang indefinitely when all slaves have terminated.
Proposed technical implementation details (optional)
Suggestion:
Add an API call to check whether a ConPTY is idle and has no active clients or pending data, and thus is safe to close, or in the alternative add an API call to ask the ConPTY to terminate as soon as its client count reaches zero and not output is pending.
The text was updated successfully, but these errors were encountered: