Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Nov 2003 01:27:41 -0800
From:      Guy Harris <guy@alum.mit.edu>
To:        Bruce Evans <bde@zeta.org.au>
Cc:        fenner@FreeBSD.org
Subject:   Re: bpf/pcap are weird
Message-ID:  <20031121012741.G329@quadrajet.sonic.net>

next in thread | raw e-mail | index | archive | help
> > bpfpoll() is reported to be broken; see PR 36219.
> 
> Yes, that's the PR that indicated that "select()"/"poll()" don't, in
> fact, work correctly with timeouts.
> 
> That was fixed in 4.5...
> 
> > Rev.1.113 of bpf.c may have disturbed this.
> 
> ...but might have been re-broken.
> 
> > It removed the comment which said that
> > bpf_ready() doesn't acually imitate resultof(FIONREAD) != 0.
> 
> ...and it also removed the check for "d->bd_state == BPF_TIMED_OUT" that
> made "select()"/"poll()" work with timeouts.

I didn't read the code fully - no, it didn't.  Revision 1.113 changed

	if (events & (POLLIN | POLLRDNORM)) {
		/*
		 * An imitation of the FIONREAD ioctl code.
		 * XXX not quite.  An exact imitation:
		 *      if (d->b_slen != 0 ||
		 *          (d->bd_hbuf != NULL && d->bd_hlen != 0)
		 */
		if (d->bd_hlen != 0 ||
		    ((d->bd_immediate || d->bd_state == BPF_TIMED_OUT) &&
		    d->bd_slen != 0))
			revents |= events & (POLLIN | POLLRDNORM);
		else {
			selrecord(td, &d->bd_sel);
			/* Start the read timeout if necessary. */
			if (d->bd_rtout > 0 && d->bd_state == BPF_IDLE) {
				callout_reset(&d->bd_callout, d->bd_rtout,
				    bpf_timed_out, d);
				d->bd_state = BPF_WAITING;
			}
		}
	}

to

	if (events & (POLLIN | POLLRDNORM)) {
		if (bpf_ready(d))
			revents |= events & (POLLIN | POLLRDNORM);
		else {
			selrecord(td, &d->bd_sel);
			/* Start the read timeout if necessary. */
			if (d->bd_rtout > 0 && d->bd_state == BPF_IDLE) {
				callout_reset(&d->bd_callout, d->bd_rtout,
				    bpf_timed_out, d);
				d->bd_state = BPF_WAITING;
			}
		}
	}

but revision 1.23 of "bpfdesc.h" introduce a macro "bpf_ready(bd)" that
does

	#define bpf_ready(bd)                                            \
		((bd)->bd_hlen != 0 ||                                   \
		 (((bd)->bd_immediate || (bd)->bd_state == BPF_TIMED_OUT) && \
		  (bd)->bd_slen != 0))

so the actual "bpf_poll()" code doesn't change.

Revision 1.23 was MFC'ed to the 4.x branch in revision 1.14.2.3, which
is in 4.9.

(Also, the problem I mentioned with FreeBSD 4.4 not supporting the
workaround for "select()" not working is in FreeBSD 4.3 as well.)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20031121012741.G329>