[PATCH v5] Cygwin: pty: Revise code waiting for forwarding again.

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH v5] Cygwin: pty: Revise code waiting for forwarding again.

Takashi Yano
- After commit 6cc299f0e20e4b76f7dbab5ea8c296ffa4859b62, outputs of
  cygwin programs which call both printf() and WriteConsole() are
  frequently distorted. This patch fixes the issue.
---
 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 35190c0fe..9ce321c8c 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2209,6 +2209,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 71a1f42ba..3e5017f19 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;
@@ -2680,6 +2680,16 @@ fhandler_pty_slave::set_freeconsole_on_close (bool 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
 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;
       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 alerady has data to transfer.
+     If the time without transfer exceeds 32 msec, the
+     forwarding has 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; }
--
2.21.0

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH v5] Cygwin: pty: Revise code waiting for forwarding again.

Corinna Vinschen-2
On Jan 27 20:22, Takashi Yano wrote:
> - After commit 6cc299f0e20e4b76f7dbab5ea8c296ffa4859b62, outputs of
>   cygwin programs which call both printf() and WriteConsole() are
>   frequently distorted. This patch fixes the issue.
> ---
>  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(-)

Pushed.


Thanks,
Corinna

--
Corinna Vinschen
Cygwin Maintainer

signature.asc (849 bytes) Download Attachment