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:
		
							parent
							
								
									5ba41ad6e9
								
							
						
					
					
						commit
						e38f2dc9b9
					
				|  | @ -2218,6 +2218,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)) | ||||||
|  |  | ||||||
|  | @ -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 ()) | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -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; } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue