-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Low reliability of VT replies #17775
Comments
I believe this is caused by #16224. Since the terminal lock isn't held anymore, any thread can write into the input pipe concurrently. In our case that's the VT parser thread sending VT responses and the UI thread sending cursor messages. |
Thanks.
Just to confirm: bad replies happen even when there are no cursor messages (ENABLE_MOUSE_INPUT is not set) or any other input. Also, I don't know if it's related or not, but every time I terminate the repro with ^C the shell crashes: I thought maybe I've built WT wrong or something, but the fact that it fails in |
Aside from mouse messages and keyboard input, we also send focus events to ConPTY from the UI thread.
Yeah, I noticed that as well. I believe it's dotnet/runtime#88697 which points to our issue #15859. I've set it to be fixed in v1.23 now. The weirdest thing is that this issue doesn't occur anymore after my PR. (It does still break PSReadLine though, because |
* Repurposes `_sendInputToConnection` to send output to the connection no matter whether the terminal is read-only or not. Now `SendInput` is the function responsible for the UI handling. * Buffers responses in a VT string into a single string before sending it as a response all at once. This reduces the chances for the UI thread to insert cursor positions and similar into the input pipe, because we're not constantly unlocking the terminal lock anymore for every response. The only way now that unrelated inputs are inserted into the input pipe is because the VT requests (e.g. DA1, DSR, etc.) are broken up across >1 reads. This also fixes VT responses in read-only panes. Closes #17775 ## Validation Steps Performed * Repeatedly run `echo ^[[c` in cmd. DA1 responses don't stack & always stay the same ✅ * Run nvim in WSL. Doesn't deadlock when pasting 1MB. ✅ * Run the repro from #17775, which requests a ton of OSC 4 (color palette) responses. Jiggle the cursor on top of the window. Responses never get split up. ✅
Thanks for such a quick fix! |
* Repurposes `_sendInputToConnection` to send output to the connection no matter whether the terminal is read-only or not. Now `SendInput` is the function responsible for the UI handling. * Buffers responses in a VT string into a single string before sending it as a response all at once. This reduces the chances for the UI thread to insert cursor positions and similar into the input pipe, because we're not constantly unlocking the terminal lock anymore for every response. The only way now that unrelated inputs are inserted into the input pipe is because the VT requests (e.g. DA1, DSR, etc.) are broken up across >1 reads. This also fixes VT responses in read-only panes. Closes #17775 * Repeatedly run `echo ^[[c` in cmd. DA1 responses don't stack & always stay the same ✅ * Run nvim in WSL. Doesn't deadlock when pasting 1MB. ✅ * Run the repro from #17775, which requests a ton of OSC 4 (color palette) responses. Jiggle the cursor on top of the window. Responses never get split up. ✅ (cherry picked from commit b07589e) Service-Card-Id: PVTI_lADOAF3p4s4AmhmszgSK_Dw Service-Version: 1.21
Windows Terminal version
Latest source
Windows build number
10.0.19045.4780
Other Software
No
Steps to reproduce
I want to query some terminal state, in particular the latest and greatest palette (#17729).
To do so, I build a bunch of those
"\x1b]4;N;?\x1b\\"
, send them in one go and wait for the reply.Since I want to support not only the latest nightlies and do not want the older versions to deadlock on unknown queries, I prepend and append another query, the one that even prehistoric versions understand:
"\x1b[c"
.If there is something between those DA replies, it must be the one I need.
If there are only two DA replies, then it is probably not supported.
This approach works flawlessly in OpenConsole.
In WT, however, not so much: way, way too often random parts of the reply are simply missing.
Code
Expected Behavior
The program should print "Everything is OK" in a loop indefinitely and nothing else:
Actual Behavior
The program prints "Everything is OK" a few times, then it detects errors due to missing bits in the reply, e.g.
Eventually it deadlocks in
ReadConsole
.Adding a delay between sending the query and reading the reply improves the situation dramatically, but still not to 100% and it does not feel like the right thing to do: fixing issues with
Sleep(N)
never works in the long term.Splitting it to smaller queries also helps, but again, it is guesswork.
Overall it is about 2700 characters to send and about 7000 to receive. It does not look like something humongous by modern standards.
Moving the mouse or pressing keyboard keys noticeably increases the error rate. Again, only in WT.
The text was updated successfully, but these errors were encountered: