summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Yano <takashi.yano@nifty.ne.jp>2020-01-27 20:22:24 +0900
committerCorinna Vinschen <corinna@vinschen.de>2020-01-28 09:33:28 +0100
commite38f2dc9b93fd237bd72c1b35b9dbfc8b0f18663 (patch)
tree4566b403e5b0e52407342a56f8329605e60b9eea
parent5ba41ad6e9f1ac3326706523fc827ac3e54466f3 (diff)
downloadcygnal-e38f2dc9b93fd237bd72c1b35b9dbfc8b0f18663.tar.gz
cygnal-e38f2dc9b93fd237bd72c1b35b9dbfc8b0f18663.tar.bz2
cygnal-e38f2dc9b93fd237bd72c1b35b9dbfc8b0f18663.zip
Cygwin: pty: Revise code waiting for forwarding again.
- After commit 6cc299f0e20e4b76f7dbab5ea8c296ffa4859b62, outputs of cygwin programs which call both printf() and WriteConsole() are frequently distorted. This patch fixes the issue.
-rw-r--r--winsup/cygwin/fhandler.h1
-rw-r--r--winsup/cygwin/fhandler_tty.cc37
-rw-r--r--winsup/cygwin/tty.cc1
-rw-r--r--winsup/cygwin/tty.h1
4 files changed, 34 insertions, 6 deletions
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index b4a5638fe..5d0c579f8 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2218,6 +2218,7 @@ class fhandler_pty_slave: public fhandler_pty_common
}
void setup_locale (void);
void set_freeconsole_on_close (bool val);
+ void wait_pcon_fwd (void);
};
#define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 870fcebbc..c1c0fb812 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -1109,7 +1109,7 @@ skip_console_setting:
}
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 ||
kill (get_ttyp ()->pcon_pid, 0) != 0)
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)
/* Wait for pty_master_fwd_thread() */
- cygwait (get_ttyp ()->fwd_done, INFINITE);
+ wait_pcon_fwd ();
get_ttyp ()->pcon_pid = 0;
get_ttyp ()->switch_to_pcon_in = false;
get_ttyp ()->switch_to_pcon_out = false;
@@ -2681,6 +2681,16 @@ fhandler_pty_slave::set_freeconsole_on_close (bool 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
fhandler_pty_slave::fixup_after_attach (bool native_maybe, int fd_set)
{
if (fd < 0)
@@ -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;
SetConsoleMode (get_output_handle (), mode);
if (!get_ttyp ()->switch_to_pcon_out)
- cygwait (get_ttyp ()->fwd_done, INFINITE);
+ wait_pcon_fwd ();
if (get_ttyp ()->pcon_pid == 0 ||
kill (get_ttyp ()->pcon_pid, 0) != 0)
get_ttyp ()->pcon_pid = myself->pid;
@@ -3009,14 +3019,29 @@ fhandler_pty_master::pty_master_fwd_thread ()
termios_printf ("Started.");
for (;;)
{
- if (::bytes_available (rlen, from_slave) && rlen == 0)
- SetEvent (get_ttyp ()->fwd_done);
+ if (get_pseudo_console ())
+ {
+ /* 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))
{
termios_printf ("ReadFile for forwarding failed, %E");
break;
}
- ResetEvent (get_ttyp ()->fwd_done);
ssize_t wlen = rlen;
char *ptr = outbuf;
if (get_pseudo_console ())
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index ef9bbc1ff..a3d4a0fc8 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -246,6 +246,7 @@ tty::init ()
term_code_page = 0;
need_redraw_screen = false;
fwd_done = NULL;
+ pcon_last_time = 0;
}
HANDLE
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index b291fd3c1..755897d7d 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -107,6 +107,7 @@ private:
UINT term_code_page;
bool need_redraw_screen;
HANDLE fwd_done;
+ DWORD pcon_last_time;
public:
HANDLE from_master () const { return _from_master; }