[newlib-cygwin] Cygwin: console: Ensure the master thread runs only when it is supposed to

Takashi Yano via Cygwin-cvs <[email protected]> Wed, 24 Jun 2026 12:45:41 +0000 (GMT)
Newsgroups gmane.os.cygwin.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3D733d5a953fa=
952ba9572ef00019f3a6c70a2da73

commit 733d5a953fa952ba9572ef00019f3a6c70a2da73
Author: Takashi Yano <[email protected]>
Date:   Wed Jun 10 23:05:29 2026 +0900

    Cygwin: console: Ensure the master thread runs only when it is supposed=
 to
   =20
    Currently, disabling cons_master_thread is done by just setting the
    flag disable_master_thread. In fact, actual suspension of master
    thread is delayed a bit. Therefore, non-cygwin program where the
    master thread should be disabled may run even though the master
    thread is running in a short time. This patch ensure that the master
    thread is suspended when non-cygwin app is running. In addition,
    while master thread is running, console mode should not be changed.
    Therefore, the order of set_input_mode() call and disabling/enabling
    master thread is swapped.
   =20
    Fixes: d2b14c303c04 ("Cygwin: console: Redesign handling of special key=
s.")
    Signed-off-by: Takashi Yano <[email protected]>
    Reviewed-by: Mark Geisert <[email protected]>

Diff:
---
 winsup/cygwin/fhandler/console.cc | 15 +++++++++------
 winsup/cygwin/release/3.6.10      |  2 ++
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/winsup/cygwin/fhandler/console.cc b/winsup/cygwin/fhandler/con=
sole.cc
index 45eff6efe..a5e6cd89d 100644
--- a/winsup/cygwin/fhandler/console.cc
+++ b/winsup/cygwin/fhandler/console.cc
@@ -439,6 +439,7 @@ fhandler_console::cons_master_thread (handle_set_t *p, =
tty *ttyp)
=20
       if (con.disable_master_thread)
 	{
+	  con.master_thread_suspended =3D true;
 	  cygwait (40);
 	  continue;
 	}
@@ -976,9 +977,9 @@ fhandler_console::setup_for_non_cygwin_app ()
      console mode. */
   if (get_ttyp ()->getpgid () =3D=3D myself->pgid)
     {
+      set_disable_master_thread (true, this);
       set_input_mode (tty::native, &tc ()->ti, get_handle_set ());
       set_output_mode (tty::native, &tc ()->ti, get_handle_set ());
-      set_disable_master_thread (true, this);
     }
 }
=20
@@ -990,7 +991,6 @@ fhandler_console::cleanup_for_non_cygwin_app (handle_se=
t_t *p)
   termios *ti =3D shared_console_info[unit] ?
     &(shared_console_info[unit]->tty_min_state.ti) : &dummy;
   /* Cleaning-up console mode for non-cygwin app. */
-  set_disable_master_thread (con.owner =3D=3D GetCurrentProcessId ());
   /* conmode can be tty::restore when non-cygwin app is
      exec'ed from login shell. */
   tty::cons_mode conmode =3D cons_mode_on_close (p);
@@ -998,6 +998,7 @@ fhandler_console::cleanup_for_non_cygwin_app (handle_se=
t_t *p)
     set_output_mode (conmode, ti, p);
   if (con.curr_input_mode !=3D conmode)
     set_input_mode (conmode, ti, p);
+  set_disable_master_thread (con.owner =3D=3D GetCurrentProcessId ());
 }
=20
 /* Return the tty structure associated with a given tty number.  If the
@@ -1190,8 +1191,8 @@ fhandler_console::bg_check (int sig, bool dontsignal)
      in the same process group. */
   if (sig =3D=3D SIGTTIN && con.curr_input_mode !=3D tty::cygwin)
     {
-      set_disable_master_thread (false, this);
       set_input_mode (tty::cygwin, &tc ()->ti, get_handle_set ());
+      set_disable_master_thread (false, this);
     }
   if (sig =3D=3D SIGTTOU && con.curr_output_mode !=3D tty::cygwin)
     set_output_mode (tty::cygwin, &tc ()->ti, get_handle_set ());
@@ -2087,8 +2088,8 @@ fhandler_console::post_open_setup (int fd)
   /* Setting-up console mode for cygwin app started from non-cygwin app. */
   if (fd =3D=3D 0)
     {
-      set_disable_master_thread (false, this);
       set_input_mode (tty::cygwin, &get_ttyp ()->ti, &handle_set);
+      set_disable_master_thread (false, this);
     }
   else if (fd =3D=3D 1 || fd =3D=3D 2)
     set_output_mode (tty::cygwin, &get_ttyp ()->ti, &handle_set);
@@ -2106,11 +2107,11 @@ fhandler_console::close (int flag)
   if (shared_console_info[unit] && (dev_t) myself->ctty =3D=3D get_device =
()
       && cons_mode_on_close (&handle_set) =3D=3D tty::restore)
     {
+      set_disable_master_thread (true, this);
       if (con.curr_output_mode !=3D tty::restore)
 	set_output_mode (tty::restore, &get_ttyp ()->ti, &handle_set);
       if (con.curr_input_mode !=3D tty::restore)
 	set_input_mode (tty::restore, &get_ttyp ()->ti, &handle_set);
-      set_disable_master_thread (true, this);
     }
=20
   if (shared_console_info[unit] && con.owner =3D=3D GetCurrentProcessId ())
@@ -4445,10 +4446,10 @@ fhandler_console::set_console_mode_to_native ()
 	fhandler_console *cons =3D (fhandler_console *) (fhandler_base *) cfd;
 	if (cons->get_device () =3D=3D cons->tc ()->getntty ())
 	  {
+	    set_disable_master_thread (true, cons);
 	    termios *cons_ti =3D &cons->tc ()->ti;
 	    set_input_mode (tty::native, cons_ti, cons->get_handle_set ());
 	    set_output_mode (tty::native, cons_ti, cons->get_handle_set ());
-	    set_disable_master_thread (true, cons);
 	    break;
 	  }
       }
@@ -4825,6 +4826,8 @@ fhandler_console::set_disable_master_thread (bool x, =
fhandler_console *cons)
   cons->acquire_input_mutex (mutex_timeout);
   con.disable_master_thread =3D x;
   cons->release_input_mutex ();
+  while (con.master_thread_suspended !=3D x)
+    Sleep (1);
 }
=20
 int
diff --git a/winsup/cygwin/release/3.6.10 b/winsup/cygwin/release/3.6.10
index 4d847829b..597cf7bdb 100644
--- a/winsup/cygwin/release/3.6.10
+++ b/winsup/cygwin/release/3.6.10
@@ -18,3 +18,5 @@ Fixes:
 - Fix race issue between starting and exiting non-cygwin apps in pty.
=20
 - Fix CR/NL conversion in accept_input() for pty.
+
+- Ensure the cons_master_thread runs only when it is really supposed to.