From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 55529 invoked by alias); 28 Jan 2020 17:02:01 -0000 Mailing-List: contact cygwin-cvs-help@cygwin.com; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: cygwin-cvs-owner@cygwin.com Received: (qmail 55446 invoked by uid 9078); 28 Jan 2020 17:02:00 -0000 Date: Tue, 28 Jan 2020 17:02:00 -0000 Message-ID: <20200128170200.55443.qmail@sourceware.org> Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin] Cygwin: pty: Revise code waiting for forwarding again. X-Act-Checkin: newlib-cygwin X-Git-Author: Takashi Yano X-Git-Refname: refs/heads/master X-Git-Oldrev: 5ba41ad6e9f1ac3326706523fc827ac3e54466f3 X-Git-Newrev: e38f2dc9b93fd237bd72c1b35b9dbfc8b0f18663 X-SW-Source: 2020-q1/txt/msg00033.txt https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=e38f2dc9b93fd237bd72c1b35b9dbfc8b0f18663 commit e38f2dc9b93fd237bd72c1b35b9dbfc8b0f18663 Author: Takashi Yano Date: Mon Jan 27 20:22:24 2020 +0900 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. Diff: --- winsup/cygwin/fhandler.h | 1 + winsup/cygwin/fhandler_tty.cc | 37 +++++++++++++++++++++++++++++++------ winsup/cygwin/tty.cc | 1 + winsup/cygwin/tty.h | 1 + 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index b4a5638..5d0c579 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 870fceb..c1c0fb8 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 ef9bbc1..a3d4a0f 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 b291fd3..755897d 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; }