- kfcount = sel->kfcount;
-
- if (kfcount > count)
- panic("selscan: count < kfcount");
-
- if (kfcount != 0) {
- funnel_state = thread_funnel_set(kernel_flock, TRUE);
-
- proc_fdlock(p);
- for (msk = 0; msk < 3; msk++) {
- iptr = (u_int32_t *)&ibits[msk * nw];
- optr = (u_int32_t *)&obits[msk * nw];
-
- for (i = 0; i < nfd; i += NFDBITS) {
- bits = iptr[i/NFDBITS];
-
- while ((j = ffs(bits)) && (fd = i + --j) < nfd) {
- bits &= ~(1 << j);
- fp = fdp->fd_ofiles[fd];
-
- if (fp == NULL ||
- (fdp->fd_ofileflags[fd] & UF_RESERVED)) {
- proc_fdunlock(p);
- thread_funnel_set(kernel_flock, funnel_state);
- return(EBADF);
- }
- if (sel_pass == SEL_SECONDPASS) {
- wql_ptr = (char *)0;
- fp->f_flags &= ~FP_INSELECT;
- fp->f_waddr = (void *)0;
- } else {
- wql_ptr = (wql + nc * SIZEOF_WAITQUEUE_LINK);
- fp->f_flags |= FP_INSELECT;
- fp->f_waddr = (void *)wqsub;
- }
-
- context.vc_ucred = fp->f_cred;
-
- if (fp->f_ops && (fp->f_type == DTYPE_VNODE)
- && ((vp = (struct vnode *)fp->f_data) != NULLVP)
- && (vp->v_type == VCHR)
- && fo_select(fp, flag[msk], wql_ptr, &context)) {
- optr[fd/NFDBITS] |= (1 << (fd % NFDBITS));
- n++;
- }
- nc++;
- }
- }
- }
- proc_fdunlock(p);
- thread_funnel_set(kernel_flock, funnel_state);
- }