On Mon, Jan 5, 2015 at 11:01 AM, Ted Unangst <[email protected]> wrote:
...
> In the regular timeout case, I'm not sure what you're changing. There
> is a problem here though. If we're already close to the timeout
> expiring, we shouldn't sleep the full timeout, only the time left
> since we began the read.


>
> Looking at the current code, the comparison seems reversed. If we've
> just started reading, ticks == rdStart, and so adding the timeout will
> always be greater, not less, than the current ticks.
>
> I believe this diff addresses all the above issues. The current code
> works correctly for the rtout == 0 case, but sleeping for only the
> remaining timeout is much easier done by splitting it.
>
> Anyone else have thoughts? I get confused by this code every time I
> read it, perhaps because bugs obscure what it's trying to do and what
> is doing. Am I correct?
>
> Index: bpf.c
> ===================================================================
> RCS file: /cvs/src/sys/net/bpf.c,v
> retrieving revision 1.113
> diff -u -p -r1.113 bpf.c
> --- bpf.c       16 Dec 2014 18:30:04 -0000      1.113
> +++ bpf.c       5 Jan 2015 18:49:11 -0000
> @@ -430,10 +430,13 @@ bpfread(dev_t dev, struct uio *uio, int
>                 if (d->bd_rtout == -1) {
>                         /* User requested non-blocking I/O */
>                         error = EWOULDBLOCK;
> +               } else if (d->bd_rtout == 0) {
> +                       error = tsleep(d, PRINET|PCATCH, "bpf", 0);
>                 } else {
> -                       if ((d->bd_rdStart + d->bd_rtout) < ticks) {
> -                               error = tsleep((caddr_t)d, PRINET|PCATCH, 
> "bpf",
> -                                   d->bd_rtout);
> +                       int elapsed = ticks - d->bd_rdStart;
> +                       if (elapsed < d->bd_rtout) {
> +                               error = tsleep(d, PRINET|PCATCH, "bpf",
> +                                   d->bd_rtout - elapsed);
>                         } else
>                                 error = EWOULDBLOCK;
>                 }
>

Reply via email to