Repository navigation
Do not share terminal state between concurrent terminals in one process - #44
Merged
alexey-milovidov merged 1 commit intoOct 12, 2026
Merged
Conversation
Several terminals can work concurrently in one process, e.g. client sessions embedded into a server, each attached to its own pseudo-terminal. - Only a terminal that installed the `SIGWINCH` handler registers itself as the receiver of window size notifications, the registration is atomic, and a terminal unregisters only itself. - The partially read UTF-8 sequence in `read_unicode_character`, the modifiers of the escape sequence being parsed, and the buffer of `ansi_color` are per thread. Previously concurrent multi-byte input could corrupt each other, and a race allowed a one-byte out-of-bounds write. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
alexey-milovidov
added a commit
to ClickHouse/ClickHouse
that referenced
this pull request
Oct 12, 2026
`master` of `replxx` now contains the fix of the shared terminal state. The new commit merges it with the history recall changes used by ClickHouse and fixes Ctrl-V blocking after the esc delay support from `master`. Related: ClickHouse/replxx#44 Related: ClickHouse/replxx#46 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
azat
reviewed
Oct 13, 2026
Comment on lines
+327
to
+328
| thread_local char8_t utf8String[5]; | ||
| thread_local size_t utf8Count = 0; |
Member
There was a problem hiding this comment.
This is not enough, multiple terminals may work over different fds, and this states should be per-fd, we need to move this state into the Terminal object
I've fixed it here - #47
alexey-milovidov
added a commit
that referenced
this pull request
Oct 13, 2026
`master` got a simpler version of the same fix (#44) and the esc delay support. The conflicts are resolved in favor of this branch: the UTF-8 decoder state is kept in `Terminal`, the escape sequence routines take the `Terminal`, and the `SIGWINCH` disposition is restored. The esc delay parameter from `master` is passed through, `Terminal::read_unicode_character` waits with `poll` as on `master`, and `read_verbatim` still does not wait after the first character. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Several terminals can work concurrently in one process. ClickHouse does this with client sessions embedded into the server (the web terminal and SSH), each attached to its own pseudo-terminal. Some replxx state was process-wide, so these sessions could affect each other:
SIGWINCHreceiver (_terminal_): every terminal that entered raw mode stored itself in a non-atomic global, and leaving raw mode cleared it even if another terminal had registered. Now only a terminal that installed the window change handler registers itself, the registration is atomic (so the signal handler can read it safely), and a terminal unregisters only itself.read_unicode_character: concurrent multi-byte input could corrupt each other. Also, a race between the bounds check and the write allowed a one-byte out-of-bounds write. The state is nowthread_local.thisKeyMetaCtrl): concurrent terminals could get each other's Ctrl/Alt bits. Nowthread_local.ansi_colorbuffer: nowthread_local. The result is consumed right away by the calling thread.The remaining mutable-looking globals are set only during static initialization.
ClickHouse PR: ClickHouse/ClickHouse#125510
ClickHouse currently uses this change on top of the
clickhouse/history-recalled-hints-fixbranch (commit e8e3d2f). This PR has the same change cherry-picked ontomaster.🤖 Generated with Claude Code