Thank you :) I suspect that's too late to get this into FreeBSD 10.1?
On Thu, 9 Oct 2014 02:30:39 +0000 (UTC) Marcel Moolenaar <mar...@freebsd.org> wrote: > Author: marcel > Date: Thu Oct 9 02:30:38 2014 > New Revision: 272789 > URL: https://svnweb.freebsd.org/changeset/base/272789 > > Log: > Fix draining in ttydev_leave(): > 1. ERESTART is not only returned when the revoke count changed. It > is also returned when a signal is received. While a change in > the revoke count should be ignored, a signal should not. > 2. Waiting until the output queue is entirely drained can cause a > hang when the underlying device is stuck or broken. > > Have tty_drain() take care of this by telling it when we're leaving. > When leaving, tty_drain() will use a timed wait to address point 2 > above and it will check the revoke count to handle point 1 above. > The timeout is set to 1 second, which is arbitrary and long enough > to expect a change in the output queue. > > Discussed with: jilles@ > Reported by: Yamagi Burmeister <li...@yamagi.org> > > Modified: > head/sys/kern/tty.c > > Modified: head/sys/kern/tty.c > ============================================================================== > --- head/sys/kern/tty.c Thu Oct 9 02:24:34 2014 (r272788) > +++ head/sys/kern/tty.c Thu Oct 9 02:30:38 2014 (r272789) > @@ -123,9 +123,10 @@ tty_watermarks(struct tty *tp) > } > > static int > -tty_drain(struct tty *tp) > +tty_drain(struct tty *tp, int leaving) > { > - int error; > + size_t bytesused; > + int error, revokecnt; > > if (ttyhook_hashook(tp, getc_inject)) > /* buffer is inaccessible */ > @@ -134,11 +135,27 @@ tty_drain(struct tty *tp) > while (ttyoutq_bytesused(&tp->t_outq) > 0) { > ttydevsw_outwakeup(tp); > /* Could be handled synchronously. */ > - if (ttyoutq_bytesused(&tp->t_outq) == 0) > + bytesused = ttyoutq_bytesused(&tp->t_outq); > + if (bytesused == 0) > return (0); > > /* Wait for data to be drained. */ > - error = tty_wait(tp, &tp->t_outwait); > + if (leaving) { > + revokecnt = tp->t_revokecnt; > + error = tty_timedwait(tp, &tp->t_outwait, hz); > + switch (error) { > + case ERESTART: > + if (revokecnt != tp->t_revokecnt) > + error = 0; > + break; > + case EWOULDBLOCK: > + if (ttyoutq_bytesused(&tp->t_outq) < bytesused) > + error = 0; > + break; > + } > + } else > + error = tty_wait(tp, &tp->t_outwait); > + > if (error) > return (error); > } > @@ -191,10 +208,8 @@ ttydev_leave(struct tty *tp) > > /* Drain any output. */ > MPASS((tp->t_flags & TF_STOPPED) == 0); > - if (!tty_gone(tp)) { > - while (tty_drain(tp) == ERESTART) > - ; > - } > + if (!tty_gone(tp)) > + tty_drain(tp, 1); > > ttydisc_close(tp); > > @@ -1528,7 +1543,7 @@ tty_generic_ioctl(struct tty *tp, u_long > > /* Set terminal flags through tcsetattr(). */ > if (cmd == TIOCSETAW || cmd == TIOCSETAF) { > - error = tty_drain(tp); > + error = tty_drain(tp, 0); > if (error) > return (error); > if (cmd == TIOCSETAF) > @@ -1707,7 +1722,7 @@ tty_generic_ioctl(struct tty *tp, u_long > } > case TIOCDRAIN: > /* Drain TTY output. */ > - return tty_drain(tp); > + return tty_drain(tp, 0); > case TIOCCONS: > /* Set terminal as console TTY. */ > if (*(int *)data) { > _______________________________________________ > svn-src-...@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/svn-src-all > To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org" -- Homepage: www.yamagi.org XMPP: yam...@yamagi.org GnuPG/GPG: 0xEFBCCBCB _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"