[PATCH v7 3/7] Cygwin: console: Use input_mutex in the parent PTY in master thread
Takashi Yano
takashi.yano@nifty.ne.jp
Sat Mar 28 10:28:15 GMT 2026
Hi Johannes,
On Fri, 27 Mar 2026 15:20:42 +0100 (CET)
Johannes Schindelin wrote:
> Hi Takashi,
>
> On Wed, 25 Mar 2026, Takashi Yano wrote:
>
> > If the console is originating from pseudo console, the input into
> > console is comming from PTY master. Therefore, input_mutex in PTY
> > can be used to avoid conflicts between fhandler_pty_master::write()
> > and cons_master_thread().
>
> Nit: "comming" -> "coming".
>
> More substantially, I think the commit message would benefit from
> explaining _why_ `cons_master_thread()` and `fhandler_pty_master::write()`
> can conflict. As I understand it, the mechanism is this:
>
> When the pseudo console is active, `cons_master_thread()` runs inside
> the Cygwin process that inherited the pseudo console from its parent
> PTY. It reads all `INPUT_RECORD`s from the console input buffer via
> `ReadConsoleInputW()`, processes signal-generating events (e.g. Ctrl+C),
> and writes the remaining records back via `WriteConsoleInputW()`.
> Meanwhile, the PTY master process (e.g. mintty) calls
> `fhandler_pty_master::write()`, which writes keystrokes to `to_slave_nat`
> (one end of the nat pipe). Conhost reads from the other end of that pipe,
> parses the byte stream through its VT input path, and inserts the
> resulting `INPUT_RECORD`s into the console input buffer.
>
> If `cons_master_thread()` reads the buffer and removes a signal record
> while conhost is simultaneously inserting new records from the PTY
> master's write, the verify step (`inrec_eq()`) finds records in the
> buffer that were not part of the original read, reports a mismatch, and
> enters the fixup path. That fixup path itself can disturb the record
> order, turning what was merely an interference into an actual problem.
> Acquiring the PTY's `input_mutex` in `cons_master_thread()` prevents
> `fhandler_pty_master::write()` from feeding new bytes into the pipe
> while the read-process-writeback-verify cycle is in progress.
>
> That reasoning is what makes this patch convincing, and I think it should
> be in the commit message so that future readers do not have to
> reconstruct it.
>
> Note that the serialization is not fully airtight: even when
> `cons_master_thread()` holds `input_mutex` and blocks
> `fhandler_pty_master::write()` from feeding more bytes into the pipe,
> conhost might still be processing bytes that are already buffered in the
> pipe from a previous write. The mutex does not block conhost itself, only
> the master's write end. So it reduces the window for interleaving rather
> than eliminating it entirely. Is there a reason this is sufficient, or is
> the remaining window small enough in practice that it does not matter?
You are right regarding the mutex that does not eliminate the conflict
entirely. This is acceptable because the fixup code in cons_master_thread
can fix it.
Originally, this fixup code was written for pure console input, and since
the console provides no way to block the user’s keystrokes, it was designed
so that the fixup code resolves the conflicts between keystrokes and master
thread. Therefore, the mutex added by this patch is actually not essential.
However, reducing fix-up is better than nothing, I think.
--
Takashi Yano <takashi.yano@nifty.ne.jp>
More information about the Cygwin-patches
mailing list