[newlib-cygwin] Cygwin: console: Use input_mutex in the parent PTY in master thread
Takashi Yano via Cygwin-cvs <[email protected]> Sun, 29 Mar 2026 00:43:55 +0000 (GMT)
| Newsgroups | gmane.os.cygwin.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3Dc4fb720afcf= 120a028f776dde47cacd2d91f3a14 commit c4fb720afcf120a028f776dde47cacd2d91f3a14 Author: Takashi Yano <[email protected]> Date: Tue Mar 17 11:04:52 2026 +0900 Cygwin: console: Use input_mutex in the parent PTY in master thread =20 If the console is originating from pseudo console, the input into console is coming from PTY master. This is because: =20 When the pseudo console is active, and a cygwin process is started from non-cygwin process, `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_na= t` (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. =20 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. =20 Use parent input_mutex as well as input_mutex in console device in cons_master_thread(). =20 Fixes: 04f386e9af99 ("Cygwin: console: Inherit pcon hand over from pare= nt pty") Signed-off-by: Takashi Yano <[email protected]> Reviewed-by: Johannes Schindelin <[email protected]> Diff: --- winsup/cygwin/fhandler/console.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/winsup/cygwin/fhandler/console.cc b/winsup/cygwin/fhandler/con= sole.cc index 2a52ba575..39c4f6ff0 100644 --- a/winsup/cygwin/fhandler/console.cc +++ b/winsup/cygwin/fhandler/console.cc @@ -63,6 +63,7 @@ fhandler_console::console_state NO_COPY static bool NO_COPY inside_pcon_checked =3D false; static bool NO_COPY inside_pcon =3D false; static int NO_COPY parent_pty; +static HANDLE NO_COPY parent_pty_input_mutex =3D NULL; =20 bool NO_COPY fhandler_console::invisible_console; =20 @@ -465,6 +466,8 @@ fhandler_console::cons_master_thread (handle_set_t *p, = tty *ttyp) continue; } total_read =3D 0; + if (inside_pcon && parent_pty_input_mutex) + WaitForSingleObject (parent_pty_input_mutex, mutex_timeout); switch (cygwait (p->input_handle, (DWORD) 0)) { case WAIT_OBJECT_0: @@ -489,6 +492,8 @@ fhandler_console::cons_master_thread (handle_set_t *p, = tty *ttyp) default: /* Error */ free (input_rec); free (input_tmp); + if (inside_pcon && parent_pty_input_mutex) + ReleaseMutex (parent_pty_input_mutex); ReleaseMutex (p->input_mutex); return; } @@ -666,6 +671,8 @@ remove_record: while (true); } skip_writeback: + if (inside_pcon && parent_pty_input_mutex) + ReleaseMutex (parent_pty_input_mutex); ReleaseMutex (p->input_mutex); cygwait (40); } @@ -1971,6 +1978,8 @@ fhandler_console::setup_pcon_hand_over () inside_pcon =3D true; atexit (fhandler_console::pcon_hand_over_proc); parent_pty =3D i; + parent_pty_input_mutex =3D + cygwin_shared->tty[i]->open_input_mutex (MAXIMUM_ALLOWED); break; } } @@ -1997,6 +2006,7 @@ fhandler_console::pcon_hand_over_proc (void) else system_printf("Acquiring pcon_ho_mutex failed."); ReleaseMutex (mtx); + ForceCloseHandle (parent_pty_input_mutex); } =20 bool