Index: sys_generic.c =================================================================== --- sys_generic.c (revision 187579) +++ sys_generic.c (working copy) @@ -947,38 +947,44 @@ fd_mask **ibits, **obits; int nfd; { - int msk, i, fd; - fd_mask bits; + int msk, n, i, j, flags, end, fd; struct file *fp; - int n = 0; /* Note: backend also returns POLLHUP/POLLERR if appropriate. */ static int flag[3] = { POLLRDNORM, POLLWRNORM, POLLRDBAND }; struct filedesc *fdp = td->td_proc->p_fd; + n = 0; FILEDESC_SLOCK(fdp); - for (msk = 0; msk < 3; msk++) { - if (ibits[msk] == NULL) - continue; - for (i = 0; i < nfd; i += NFDBITS) { - bits = ibits[msk][i/NFDBITS]; - /* ffs(int mask) not portable, fd_mask is long */ - for (fd = i; bits && fd < nfd; fd++, bits >>= 1) { - if (!(bits & 1)) + for (i = 0, fd = 0; i < nfd; i++) { + end = imin(fd + NFDBITS, nfd); + for (j = 0; fd < end; j++, fd++) { + flags = 0; + for (msk = 0; msk < 3; msk++) { + if (ibits[msk] == NULL) continue; - if ((fp = fget_locked(fdp, fd)) == NULL) { - FILEDESC_SUNLOCK(fdp); - return (EBADF); - } - selfdalloc(td, (void *)(uintptr_t)fd); - if (fo_poll(fp, flag[msk], td->td_ucred, - td)) { + if ((ibits[msk][i] & (1 << j)) == 0) + continue; + flags |= flag[msk]; + } + if (flags == 0) + continue; + if ((fp = fget_locked(fdp, fd)) == NULL) { + FILEDESC_SUNLOCK(fdp); + return (EBADF); + } + selfdalloc(td, (void *)(uintptr_t)fd); + if (fo_poll(fp, flags, td->td_ucred, td)) { + for (msk = 0; msk < 3; msk++) { + if ((flags & flag[msk]) == 0) + continue; obits[msk][(fd)/NFDBITS] |= ((fd_mask)1 << ((fd) % NFDBITS)); - n++; } + n++; } } } + FILEDESC_SUNLOCK(fdp); td->td_retval[0] = n; return (0);