[PATCH 4/4] Cygwin: pty: Guard accept_input routing and flush stale readahead in fast path
Johannes Schindelin
Johannes.Schindelin@gmx.de
Fri Mar 27 11:23:50 GMT 2026
Hi Takashi,
On Wed, 18 Mar 2026, Takashi Yano wrote:
> On Mon, 02 Mar 2026 14:24:40 +0000
> "Johannes Schindelin wrote:
> > From: Johannes Schindelin <johannes.schindelin@gmx.de>
> >
> > diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
> > index dd7ea9038..fcff53d88 100644
> > --- a/winsup/cygwin/fhandler/pty.cc
> > +++ b/winsup/cygwin/fhandler/pty.cc
> > @@ -489,6 +489,7 @@ fhandler_pty_master::accept_input ()
> > HANDLE write_to = get_output_handle ();
> > tmp_pathbuf tp;
> > if (to_be_read_from_nat_pipe ()
> > + && !get_ttyp ()->pcon_activated
> > && get_ttyp ()->pty_input_state == tty::to_nat)
> > {
> > /* This code is reached if non-cygwin app is foreground and
> > @@ -2208,8 +2209,18 @@ fhandler_pty_master::write (const void *ptr, size_t len)
> > WaitForSingleObject (input_mutex, mutex_timeout);
> > if (to_be_read_from_nat_pipe () && get_ttyp ()->pcon_activated
> > && get_ttyp ()->pty_input_state == tty::to_nat)
> > - { /* Reaches here when non-cygwin app is foreground and pseudo console
> > - is activated. */
> > + {
> > + /* Flush any stale readahead data from a prior line_edit call that
> > + ran while pty_input_state was temporarily to_cyg (e.g. during a
> > + setpgid_aux transition when a cygwin child of the native process
> > + started or exited). Without this, the readahead contents would
> > + be stranded and emitted after the direct WriteFile below,
> > + breaking chronological order. */
> > + if (get_readahead_valid ())
> > + {
> > + accept_input ();
>
> Does the code path really reach here?
> At the end of pcon_start phase, accept_input() is already called as
> shown below. After that, transfer_input (tty::to_nat, ...) is called.
> Therefore, in the pcon_activated state, all key input will go to nat-
> pipe, not to readahead-buffer/cyg-pipe.
>
> if (!get_ttyp ()->pcon_start)
> { /* Pseudo console initialization has been done in above code. */
> pinfo pp (get_ttyp ()->pcon_start_pid);
> if (get_ttyp ()->switch_to_nat_pipe
> && pp && pp->pgid == get_ttyp ()->getpgid ()
> && get_ttyp ()->pty_input_state_eq (tty::to_cyg))
> {
> /* This accept_input() call is needed in order to transfer input
> which is not accepted yet to non-cygwin pipe. */
> WaitForSingleObject (input_mutex, mutex_timeout);
> if (get_readahead_valid ())
> accept_input (); // <========== This
> acquire_attach_mutex (mutex_timeout);
> fhandler_pty_slave::transfer_input (tty::to_nat, from_master,
> get_ttyp (),
> input_available_event);
> release_attach_mutex ();
> ReleaseMutex (input_mutex);
> }
> get_ttyp ()->pcon_start_pid = 0;
> }
>
> What situation do you assume? Is there any case that the key input goes
> into cyg-pipe during pcon_activated other than mask_switch_to_nat_pipe()
> case?
In my AutoHotKey-based tests, this patch was required to fix the keystroke
out-of-order delivery.
However, adding `!pcon_activated` broke the routing in the `disable_pcon
case`. The readahead flush was addressing a symptom of the oscillation
rather than the root cause.
In your v7 series, `accept_input()` routes to the `nat` pipe whenever
`to_be_read_from_nat_pipe() && pty_input_state == to_nat`, regardless of
`pcon_activated`, which does not have the shortcomings of this here patch.
The readahead flush I added in this patch is handled differently (and
better) by your v7 4/7 via the `input_transferred_to_cyg`.
In short: I retract all of my patches, and thank you profusely for taking
the time to review them.
Ciao,
Johannes
More information about the Cygwin-patches
mailing list