svn commit: r272789 - head/sys/kern
Yamagi Burmeister
lists at yamagi.org
Sat Oct 11 07:21:01 UTC 2014
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 <marcel at 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 <lists at 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-all at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/svn-src-all
> To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
--
Homepage: www.yamagi.org
XMPP: yamagi at yamagi.org
GnuPG/GPG: 0xEFBCCBCB
More information about the svn-src-all
mailing list