FreeBSD/sys/kern/kern_event.c
/*
 * Remove all knotes referencing a specified fd must be called with FILEDESC
 * lock.  This prevents a race where a new fd comes along and occupies the
 * entry and we attach a knote to the fd.
 */
Remove all knotes referencing a specified fd must be called with FILEDESC
lock.  This prevents a race where a new fd comes along and occupies the
entry and we attach a knote to the fd.
Remove all knotes referencing a specified fd must be called with FILEDESC lock . This prevents a race where a new fd comes along and occupies the entry and we attach a knote to the fd .
void
knote_fdclose(struct thread *td, int fd)
{
	struct filedesc *fdp = td->td_proc->p_fd;
	struct kqueue *kq;
	struct knote *kn;
	int influx;
	FILEDESC_XLOCK_ASSERT(fdp);
	TAILQ_FOREACH(kq, &fdp->fd_kqlist, kq_list) {
		KQ_LOCK(kq);
again:
		influx = 0;
		while (kq->kq_knlistsize > fd &&
		    (kn = SLIST_FIRST(&kq->kq_knlist[fd])) != NULL) {
			if (kn->kn_status & KN_INFLUX) {
				if (influx)
					wakeup(kq);
				kq->kq_state |= KQ_FLUXWAIT;
				msleep(kq, &kq->kq_lock, PSOCK, "kqflxwt", 0);
				goto again;
			}
			kn->kn_status |= KN_INFLUX;
			KQ_UNLOCK(kq);
			if (!(kn->kn_status & KN_DETACHED))
				kn->kn_fop->f_detach(kn);
			knote_drop(kn, td);
			influx = 1;
			KQ_LOCK(kq);
		}
		KQ_UNLOCK_FLUX(kq);
	}
}
void knote_fdclose ( struct thread * td , int fd ) { struct filedesc * fdp = td -> td_proc -> p_fd ; struct kqueue * kq ; struct knote * kn ; int influx ; FILEDESC_XLOCK_ASSERT ( fdp ) ; TAILQ_FOREACH ( kq , & fdp -> fd_kqlist , kq_list ) { KQ_LOCK ( kq ) ; again : influx = 0 ; while ( kq -> kq_knlistsize > fd && ( kn = SLIST_FIRST ( & kq -> kq_knlist [ fd ] ) ) != NULL ) { if ( kn -> kn_status & KN_INFLUX ) { if ( influx ) wakeup ( kq ) ; kq -> kq_state |= KQ_FLUXWAIT ; msleep ( kq , & kq -> kq_lock , PSOCK , " " , 0 ) ; goto again ; } kn -> kn_status |= KN_INFLUX ; KQ_UNLOCK ( kq ) ; if ( ! ( kn -> kn_status & KN_DETACHED ) ) kn -> kn_fop -> f_detach ( kn ) ; knote_drop ( kn , td ) ; influx = 1 ; KQ_LOCK ( kq ) ; } KQ_UNLOCK_FLUX ( kq ) ; } }
Remove all knotes referencing a specified fd must be called with FILEDESC
 lock.
Remove all knotes referencing a specified fd must be called with FILEDESC lock .
/*
	 * We shouldn't have to worry about new kevents appearing on fd
	 * since filedesc is locked.
	 */ /* someone else might be waiting on our knote */