diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 71386a06e..cd99d0c29 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,13 @@ +2012-10-11 Christopher Faylor + + * fhandler_termios.cc (fhandler_termios::line_edit): Don't manipulate + output_mutex on CTRL-S/CTRL-Q to avoid a deadlock. + * fhandler_tty.cc (fhandler_pty_slave::write): Loop when output_stopped + is detected before acquiring output_mutex. Acquire output_mutex in the + loop for each write. + * tty.h: Remove some obsolete defines. + (tty_min::output_stopped): Make 'bool'. + 2012-10-10 Corinna Vinschen * include/cygwin/in.h (struct in_addr): Guard with s_addr to avoid diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc index 18afacf1d..956786fae 100644 --- a/winsup/cygwin/fhandler_termios.cc +++ b/winsup/cygwin/fhandler_termios.cc @@ -286,17 +286,13 @@ fhandler_termios::line_edit (const char *rptr, int nread, termios& ti) if (CCEQ (ti.c_cc[VSTOP], c)) { if (!tc ()->output_stopped) - { - tc ()->output_stopped = 1; - acquire_output_mutex (INFINITE); - } + tc ()->output_stopped = true; continue; } else if (CCEQ (ti.c_cc[VSTART], c)) { restart_output: - tc ()->output_stopped = 0; - release_output_mutex (); + tc ()->output_stopped = false; continue; } else if ((ti.c_iflag & IXANY) && tc ()->output_stopped) diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 034a5a018..dccbf13ea 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -645,8 +645,6 @@ fhandler_pty_slave::write (const void *ptr, size_t len) push_process_state process_state (PID_TTYOU); - acquire_output_mutex (INFINITE); - while (len) { n = MIN (OUT_BUFFER_SIZE, len); @@ -654,6 +652,10 @@ fhandler_pty_slave::write (const void *ptr, size_t len) ptr = (char *) ptr + n; len -= n; + while (tc ()->output_stopped) + cygwait (10); + acquire_output_mutex (INFINITE); + /* Previous write may have set write_error to != 0. Check it here. This is less than optimal, but the alternative slows down pty writes enormously. */ @@ -664,7 +666,9 @@ fhandler_pty_slave::write (const void *ptr, size_t len) break; } - if (WriteFile (get_output_handle (), buf, n, &n, NULL) == FALSE) + DWORD res = WriteFile (get_output_handle (), buf, n, &n, NULL); + release_output_mutex (); + if (!res) { DWORD err = GetLastError (); termios_printf ("WriteFile failed, %E"); @@ -677,10 +681,10 @@ fhandler_pty_slave::write (const void *ptr, size_t len) } raise (SIGHUP); /* FIXME: Should this be SIGTTOU? */ towrite = (DWORD) -1; + release_output_mutex (); break; } } - release_output_mutex (); return towrite; } diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h index 4dc0395f5..65f184997 100644 --- a/winsup/cygwin/tty.h +++ b/winsup/cygwin/tty.h @@ -19,12 +19,10 @@ details. */ /* Input/Output/ioctl events */ -#define RESTART_OUTPUT_EVENT "cygtty.output.restart" #define INPUT_AVAILABLE_EVENT "cygtty.input.avail" #define OUTPUT_MUTEX "cygtty.output.mutex" #define INPUT_MUTEX "cygtty.input.mutex" #define TTY_SLAVE_ALIVE "cygtty.slave_alive" -#define TTY_MASTER_ALIVE "cygtty.master_alive" #include @@ -38,15 +36,15 @@ class tty_min pid_t sid; /* Session ID of tty */ struct status_flags { - unsigned initialized : 1; /* Set if tty is initialized */ - unsigned rstcons : 1; /* Set if console needs to be set to "non-cooked" */ + unsigned initialized : 1; /* Set if tty is initialized */ + unsigned rstcons : 1; /* Set if console needs to be set to "non-cooked" */ } status; public: pid_t pgid; - int output_stopped; + bool output_stopped; /* FIXME: Maybe do this with a mutex someday? */ fh_devices ntty; - DWORD last_ctrl_c; /* tick count of last ctrl-c */ + DWORD last_ctrl_c; /* tick count of last ctrl-c */ bool is_console; IMPLEMENT_STATUS_FLAG (bool, initialized)