Cygwin: pty: Revise code waiting for forwarding again.

- After commit 6cc299f0e2, outputs of
  cygwin programs which call both printf() and WriteConsole() are
  frequently distorted. This patch fixes the issue.
This commit is contained in:
Takashi Yano 2020-01-27 20:22:24 +09:00 committed by Ken Brown
parent 433f2b91b4
commit f7d01f111d
4 changed files with 34 additions and 6 deletions

View File

@ -2224,6 +2224,7 @@ class fhandler_pty_slave: public fhandler_pty_common
} }
void setup_locale (void); void setup_locale (void);
void set_freeconsole_on_close (bool val); void set_freeconsole_on_close (bool val);
void wait_pcon_fwd (void);
}; };
#define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit)) #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))

View File

@ -1109,7 +1109,7 @@ skip_console_setting:
} }
else if ((fd == 1 || fd == 2) && !get_ttyp ()->switch_to_pcon_out) else if ((fd == 1 || fd == 2) && !get_ttyp ()->switch_to_pcon_out)
{ {
cygwait (get_ttyp ()->fwd_done, INFINITE); wait_pcon_fwd ();
if (get_ttyp ()->pcon_pid == 0 || if (get_ttyp ()->pcon_pid == 0 ||
kill (get_ttyp ()->pcon_pid, 0) != 0) kill (get_ttyp ()->pcon_pid, 0) != 0)
get_ttyp ()->pcon_pid = myself->pid; get_ttyp ()->pcon_pid = myself->pid;
@ -1152,7 +1152,7 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
} }
if (get_ttyp ()->switch_to_pcon_out) if (get_ttyp ()->switch_to_pcon_out)
/* Wait for pty_master_fwd_thread() */ /* Wait for pty_master_fwd_thread() */
cygwait (get_ttyp ()->fwd_done, INFINITE); wait_pcon_fwd ();
get_ttyp ()->pcon_pid = 0; get_ttyp ()->pcon_pid = 0;
get_ttyp ()->switch_to_pcon_in = false; get_ttyp ()->switch_to_pcon_in = false;
get_ttyp ()->switch_to_pcon_out = false; get_ttyp ()->switch_to_pcon_out = false;
@ -2680,6 +2680,16 @@ fhandler_pty_slave::set_freeconsole_on_close (bool val)
freeconsole_on_close = val; freeconsole_on_close = val;
} }
void
fhandler_pty_slave::wait_pcon_fwd (void)
{
acquire_output_mutex (INFINITE);
get_ttyp ()->pcon_last_time = GetTickCount ();
ResetEvent (get_ttyp ()->fwd_done);
release_output_mutex ();
cygwait (get_ttyp ()->fwd_done, INFINITE);
}
void void
fhandler_pty_slave::fixup_after_attach (bool native_maybe, int fd_set) fhandler_pty_slave::fixup_after_attach (bool native_maybe, int fd_set)
{ {
@ -2727,7 +2737,7 @@ fhandler_pty_slave::fixup_after_attach (bool native_maybe, int fd_set)
DWORD mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; DWORD mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
SetConsoleMode (get_output_handle (), mode); SetConsoleMode (get_output_handle (), mode);
if (!get_ttyp ()->switch_to_pcon_out) if (!get_ttyp ()->switch_to_pcon_out)
cygwait (get_ttyp ()->fwd_done, INFINITE); wait_pcon_fwd ();
if (get_ttyp ()->pcon_pid == 0 || if (get_ttyp ()->pcon_pid == 0 ||
kill (get_ttyp ()->pcon_pid, 0) != 0) kill (get_ttyp ()->pcon_pid, 0) != 0)
get_ttyp ()->pcon_pid = myself->pid; get_ttyp ()->pcon_pid = myself->pid;
@ -3009,14 +3019,29 @@ fhandler_pty_master::pty_master_fwd_thread ()
termios_printf ("Started."); termios_printf ("Started.");
for (;;) for (;;)
{ {
if (::bytes_available (rlen, from_slave) && rlen == 0) if (get_pseudo_console ())
SetEvent (get_ttyp ()->fwd_done); {
/* The forwarding in pseudo console sometimes stops for
16-32 msec even if it already has data to transfer.
If the time without transfer exceeds 32 msec, the
forwarding is supposed to be finished. */
const int sleep_in_pcon = 16;
const int time_to_wait = sleep_in_pcon * 2 + 1/* margine */;
get_ttyp ()->pcon_last_time = GetTickCount ();
while (::bytes_available (rlen, from_slave) && rlen == 0)
{
acquire_output_mutex (INFINITE);
if (GetTickCount () - get_ttyp ()->pcon_last_time > time_to_wait)
SetEvent (get_ttyp ()->fwd_done);
release_output_mutex ();
Sleep (1);
}
}
if (!ReadFile (from_slave, outbuf, sizeof outbuf, &rlen, NULL)) if (!ReadFile (from_slave, outbuf, sizeof outbuf, &rlen, NULL))
{ {
termios_printf ("ReadFile for forwarding failed, %E"); termios_printf ("ReadFile for forwarding failed, %E");
break; break;
} }
ResetEvent (get_ttyp ()->fwd_done);
ssize_t wlen = rlen; ssize_t wlen = rlen;
char *ptr = outbuf; char *ptr = outbuf;
if (get_pseudo_console ()) if (get_pseudo_console ())

View File

@ -246,6 +246,7 @@ tty::init ()
term_code_page = 0; term_code_page = 0;
need_redraw_screen = false; need_redraw_screen = false;
fwd_done = NULL; fwd_done = NULL;
pcon_last_time = 0;
} }
HANDLE HANDLE

View File

@ -107,6 +107,7 @@ private:
UINT term_code_page; UINT term_code_page;
bool need_redraw_screen; bool need_redraw_screen;
HANDLE fwd_done; HANDLE fwd_done;
DWORD pcon_last_time;
public: public:
HANDLE from_master () const { return _from_master; } HANDLE from_master () const { return _from_master; }