FreeBSD/sys/kern/kern_event.c
/*
 * Even if we are locked, we may need to drop the lock to allow any influx
 * knotes time to "settle".
 */
Even if we are locked, we may need to drop the lock to allow any influx
knotes time to "settle".
Even if we are locked we may need to drop the lock to allow any influx knotes time to " settle " .
void
knlist_cleardel(struct knlist *knl, struct thread *td, int islocked, int killkn)
{
	struct knote *kn, *kn2;
	struct kqueue *kq;
	KASSERT(!knl->kl_autodestroy, ("cleardel for autodestroy %p", knl));
	if (islocked)
		KNL_ASSERT_LOCKED(knl);
	else {
		KNL_ASSERT_UNLOCKED(knl);
again:		
		knl->kl_lock(knl->kl_lockarg);
	}
	SLIST_FOREACH_SAFE(kn, &knl->kl_list, kn_selnext, kn2) {
		kq = kn->kn_kq;
		KQ_LOCK(kq);
		if ((kn->kn_status & KN_INFLUX)) {
			KQ_UNLOCK(kq);
			continue;
		}
		knlist_remove_kq(knl, kn, 1, 1);
		if (killkn) {
			kn->kn_status |= KN_INFLUX | KN_DETACHED;
			KQ_UNLOCK(kq);
			knote_drop(kn, td);
		} else {
			kn->kn_flags |= (EV_EOF | EV_ONESHOT);
			KQ_UNLOCK(kq);
		}
		kq = NULL;
	}
	if (!SLIST_EMPTY(&knl->kl_list)) {
		kn = SLIST_FIRST(&knl->kl_list);
		kq = kn->kn_kq;
		KQ_LOCK(kq);
		KASSERT(kn->kn_status & KN_INFLUX,
		    ("knote removed w/o list lock"));
		knl->kl_unlock(knl->kl_lockarg);
		kq->kq_state |= KQ_FLUXWAIT;
		msleep(kq, &kq->kq_lock, PSOCK | PDROP, "kqkclr", 0);
		kq = NULL;
		goto again;
	}
	if (islocked)
		KNL_ASSERT_LOCKED(knl);
	else {
		knl->kl_unlock(knl->kl_lockarg);
		KNL_ASSERT_UNLOCKED(knl);
	}
}
void knlist_cleardel ( struct knlist * knl , struct thread * td , int islocked , int killkn ) { struct knote * kn , * kn2 ; struct kqueue * kq ; KASSERT ( ! knl -> kl_autodestroy , ( " " , knl ) ) ; if ( islocked ) KNL_ASSERT_LOCKED ( knl ) ; else { KNL_ASSERT_UNLOCKED ( knl ) ; again : knl -> kl_lock ( knl -> kl_lockarg ) ; } SLIST_FOREACH_SAFE ( kn , & knl -> kl_list , kn_selnext , kn2 ) { kq = kn -> kn_kq ; KQ_LOCK ( kq ) ; if ( ( kn -> kn_status & KN_INFLUX ) ) { KQ_UNLOCK ( kq ) ; continue ; } knlist_remove_kq ( knl , kn , 1 , 1 ) ; if ( killkn ) { kn -> kn_status |= KN_INFLUX | KN_DETACHED ; KQ_UNLOCK ( kq ) ; knote_drop ( kn , td ) ; } else { kn -> kn_flags |= ( EV_EOF | EV_ONESHOT ) ; KQ_UNLOCK ( kq ) ; } kq = NULL ; } if ( ! SLIST_EMPTY ( & knl -> kl_list ) ) { kn = SLIST_FIRST ( & knl -> kl_list ) ; kq = kn -> kn_kq ; KQ_LOCK ( kq ) ; KASSERT ( kn -> kn_status & KN_INFLUX , ( " " ) ) ; knl -> kl_unlock ( knl -> kl_lockarg ) ; kq -> kq_state |= KQ_FLUXWAIT ; msleep ( kq , & kq -> kq_lock , PSOCK | PDROP , " " , 0 ) ; kq = NULL ; goto again ; } if ( islocked ) KNL_ASSERT_LOCKED ( knl ) ; else { knl -> kl_unlock ( knl -> kl_lockarg ) ; KNL_ASSERT_UNLOCKED ( knl ) ; } }
Even if we are locked, we may need to drop the lock to allow any influx
 knotes time to "settle".
Even if we are locked we may need to drop the lock to allow any influx knotes time to " settle " .
/* need to reacquire lock since we have dropped it */ /* Make sure cleared knotes disappear soon */ /* there are still KN_INFLUX remaining */