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