-
Notifications
You must be signed in to change notification settings - Fork 8.4k
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
Persist inbox conhost; delegate control activities to it via a pipe #10415
Conversation
…opriate watching between the processes in the chain so they clean up correctly when any one of them exits (appropriately or otherwise.)
…ching to interactivity anyway. that helps it link better with existing tests.
I just realized I likely need to send a few more parameters over the IConsoleHandoff interface while I'm here for #9458. So setting to Draft until I figure that out so I don't have to rev the IID again. |
|
Could this be related to #10400? |
Unlikely; this code is only used when conhost (inside windows) spawns a secondary conhost, not when you call |
@@ -364,6 +365,8 @@ HRESULT ConsoleCreateIoThread(_In_ HANDLE Server, | |||
// from the driver... or an S_OK success. | |||
[[nodiscard]] HRESULT ConsoleEstablishHandoff([[maybe_unused]] _In_ HANDLE Server, | |||
[[maybe_unused]] HANDLE driverInputEvent, | |||
[[maybe_unused]] HANDLE hostSignalPipe, | |||
[[maybe_unused]] HANDLE hostProcessHandle, | |||
[[maybe_unused]] PCONSOLE_API_MSG connectMessage) | |||
try | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you'll probably merge conflict near here because of til::feature
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lotta comments... But no actual mistakes.
// - Creates the PTY Signal Input Thread. | ||
// Arguments: | ||
// - hPipe - a handle to the file representing the read end of the Host Signal pipe. | ||
HostSignalInputThread::HostSignalInputThread(_In_ wil::unique_hfile&& hPipe) : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need _In_
in modern C++ anymore, do we?
Also I think I need to change my opinion: I previously agreed with Dustin that &&
makes the intent of ownership transfer clear, but now that I read the code I feel like a version without any references at all is cleaner. It properly works even with prvalues, like when you want to write new HostSignalInputThread(wil::make_unique<>(...))
(if that existed), etc.
I'm not sure if it can be argued in this particular case that the &&
variant helps confer any additional meaning to future readers, what a handle called "unique" doesn't already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is between you and @DHowett then. && already confuses me and you two understand it better than me. I just want whatever works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I did drop SAL tho...)
Don't merge yet. I need to do a final e2e test after all the style feedback to make sure I didn't bungle a byte buffer. |
…ld won't build this.
Built against OS and fixed. Patched OS and tried it and confirmed the issues are still resolved. Setting automerge. |
Hello @miniksa! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
THROW_HR_IF(E_HANDLE, _hFile.get() == INVALID_HANDLE_VALUE); | ||
THROW_HR_IF(E_HANDLE, _hFile.get() == nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
huh, i thought that these were the same
moreover, however: !_hFile
is the valid way to check for presence in a wil handle
{ | ||
return NTSTATUS_FROM_WIN32(::GetLastError()); | ||
NT_RETURN_NTSTATUS(static_cast<NTSTATUS>(NTSTATUS_FROM_WIN32(::GetLastError()))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i... thought we moved to wil because there was a macro that made this less ugly, not a macro that made it more ugly 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the glory of error tracing! 🥲
It's really weird that the static_cast
is necessary...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the only plus side to this mess is that it is more debuggable with the wil tracelog. You're right... wil was supposed to solve this but then on further inspection... someone implemented like 4 of the functions and not the ones I needed (NT_RETURN_NTSTATUS_IF
and NT_RETURN_NTSTATUS_IF_WIN32_BOOL_FALSE
etc.)
🎉 Handy links: |
Persist inbox conhost; delegate control activities to it via a pipe
PR Checklist
Detailed Description of the Pull Request / Additional comments
It turns out that there's a bit of ownership that goes on with the original inbox
conhost.exe
and the operating system/driver. The PID of that originalconhost.exe
is stowed when the initial connection is established and it is verified for several activities. This means that the plan of letting it go completely away and having theOpenConsole.exe
take over all of its activities must be slightly revised.I have tested the following two alternatives to keeping
conhost.exe
around and they do not work:conhost.exe
withOpenConsole.exe
- A.) The driver does not allow this. Once the owner is registered, it cannot be replaced. B.) There's no way of updating this information inside the client process space and it is kept there too in thekernelbase
/conclnt
data from its initial connection.Put this mental model in your head:
CMD --> Conhost (inbox) --> OpenConsole (WT Package) --> Terminal (WT Package)
So since the
conhost.exe
needs to stick around, here's what I'm doing in this PR:conhost.exe
in the OS will receive back theOpenConsole.exe
process handle on a successful handoff and is expected to remain alive until theOpenConsole.exe
exits. It's now waiting on that before it terminates itself.conhost.exe
in the OS will establish a signal channel pipe and listen for control commands fromOpenConsole.exe
in a very similar fashion to how theConPTY
signal pipe operates between the Terminal and the PTY (provided byOpenConsole.exe
in this particular example.) WhenOpenConsole.exe
needs to do something that would be verified by the OS and rejected... it will instead signal the originalconhost.exe
to do that thing and it will go through.conhost.exe
will give its own handle through toOpenConsole.exe
so it can monitor its lifetime and cleanup. If the owner is gone, the session should end..reset()
and.release()
for some of thewil::unique_any<T>
handling and it lead to leaked handles. The leaked handles meant that threads weren't aware of the other sides collapsing and wouldn't cleanup/terminate appropriately.How does this fix things?
conhost.exe
PID. If it exits, that PID isn't valid and is recycled. Thus the parameter is incorrect or other inappropriate WSL setup behaviors.conhost.exe
disappeared while something about Powershell/.NET was still starting, much like the WSL one. I believe now that it is sticking around, it will be fine.Also, this WILL require an OS update to complete improvement of functionality and I have revised the interface ID. This is considered an acceptable breaking change with no mitigation because we said this feature was an alpha preview.
Validation Steps Performed