[PATCH v2] Cygwin: console: Abort setting disable_master_thread when no con.owner

Takashi Yano takashi.yano@nifty.ne.jp
Tue Sep 15 08:20:59 GMT 2026


Hi Johannes,

On Sun, 13 Sep 2026 14:12:16 +0200 (CEST)
Johannes Schindelin wrote:
> Hi Takashi,
> 
> On Sat, 12 Sep 2026, Takashi Yano wrote:
> 
> > With the commit 733d5a953fa9 ("Cygwin: console: Ensure the master
> > thread runs only when it is supposed to"), the process which calls
> > set_disable_master_thread() hangs if the con.owner already exited,
> > because set_disable_master_thread() waits for cons_master_thread
> > accepting the status change and reflecting the current status to
> > master_thread_suspended. With this patch, set_disable_master_thread()
> > is aborted if the owner process no longer exists to avoid this
> > hang.
> > 
> > Addresses: https://cygwin.com/pipermail/cygwin/2026-September/260037.html
> > Fixes: 733d5a953fa9 ("Cygwin: console: Ensure the master thread runs only when it is supposed to")
> > Reported-by: Jay Libove Alzina <libove@felines.org>
> > Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
> > Reviewed-by:
> > ---
> > v2:
> >   Fix the race
> > 
> >  winsup/cygwin/fhandler/console.cc | 15 ++++++++++++++-
> >  1 file changed, 14 insertions(+), 1 deletion(-)
> > 
> > diff --git a/winsup/cygwin/fhandler/console.cc b/winsup/cygwin/fhandler/console.cc
> > index 5f78d0c62..4b1ba60ca 100644
> > --- a/winsup/cygwin/fhandler/console.cc
> > +++ b/winsup/cygwin/fhandler/console.cc
> > @@ -5009,11 +5009,24 @@ fhandler_console::set_disable_master_thread (bool x, fhandler_console *cons)
> >  	return;
> >      }
> >    const _minor_t unit = cons->get_minor ();
> > +  if (con.owner == 0)
> > +    /* The process that runs cons_master_thread no longer exists. */
> > +    return;
> 
> This discards a request that a replacement worker must inherit.
> 
> A reachable retired state is `con.owner=0`, `disable_master_thread=false`,
> `master_thread_suspended=true`: the worker yielded to a reader, then its
> hosting process closed a console descriptor that was not its controlling
> terminal, without requesting suspension. A surviving foreground Cygwin
> process subsequently requests suspension before starting a native
> application, but the initial guard returns without recording the true
> request. A later Cygwin process with redirected stdin and console stdout
> can adopt that console and start a replacement worker without resetting
> the false request. It therefore runs and can consume flow-control
> characters intended for the native reader. V2's later normalization cannot
> help: the initial return bypasses it.
> 
> Before this patch, the true request was recorded, and the already-true
> acknowledgement let the call finish immediately. Thus this is a regression
> in a previously completing case, not simply a different outcome for an
> already-hanging case. The defect comes from v1's guard and remains in v2.
> 
> The basic idea is: a missing worker lets us stop waiting, but not discard
> the request its replacement needs. We need to preserve or normalize the
> shared request consistently under input-state synchronization on both
> no-owner exits, without removing the dead-owner escape.

OK. What about v2 patch instead?

-- 
Takashi Yano <takashi.yano@nifty.ne.jp>


More information about the Cygwin-patches mailing list