[linux-dvb] dvr device reading hangs - patch

Johannes Stezenbach js at linuxtv.org
Thu Apr 28 19:29:34 CEST 2005


On Thu, Apr 21, 2005 at 11:35:57PM +0200, Krzysztof Matula wrote:
> Krzysztof Matula wrote:
> >SkyStar2, kernel: 2.6.10-1.760_FC3
> >
> >I'm waiting for the dvr fd with select, and then if FD_ISSET I issue a 
> >read() call to it. Usually it works perfectly well, but sometimes, 
> >especially when other thread is performing multiple repeated tunings on 
> >the forntend the read() blocks infinitely until the process is killed...
> 
> Attached is a small patch that solves the problem.
...
> --- linux/drivers/media/dvb/dvb-core/dmxdev.c	5 Apr 2005 00:54:19 -0000	1.40
> +++ linux/drivers/media/dvb/dvb-core/dmxdev.c	21 Apr 2005 21:19:07 -0000
> @@ -110,6 +110,12 @@
>  	if (non_blocking && (src->pwrite==src->pread))
>  		return -EWOULDBLOCK;
>  
> +	/* We may not block here if there are some bytes available in the 
> +	   buffer - poll() may have informed the client about that!
> +	   Note that EWOULDBLOCK will never be returned in that case. */
> +	if (src->pwrite != src->pread)
> +		non_blocking = 1;
> +	
>  	while (todo>0) {
>  		if (non_blocking && (src->pwrite==src->pread))
>  			return (count-todo) ? (count-todo) : -EWOULDBLOCK;

The patch is not correct, but isn't really wrong either ;-/

The question is: Why is there a while (todo>0) loop? My guess
is that this is a performance optimization as it probably results
in fewer read() calls. But I'm not convinced that it gives any
substantial improvement, as programs that use O_NONBLOCK seem
to work fine (e.g. VDR). Your patch is just an obfuscated version
of removing the loop.

So if we want to restore "read() after POLLIN won't block" semantics
we need to drop the loop.

Or we can document the "read() after POLLIN can block unless you use
O_NONBLOCK" behaviour.

Please cast your vote.


Johannes




More information about the linux-dvb mailing list