The kqueue_close() encountering the KN_INFLUX knotes on the kq being

closed is the legitimate situation. For instance, filedescriptor with
registered events may be closed in parallel with closing the kqueue.
Properly handle the case instead of asserting that this cannot happen.

Reported and tested by:	pho
Reviewed by:	jmg
MFC after:	2 weeks
This commit is contained in:
Konstantin Belousov 2008-05-10 11:35:32 +00:00
parent 5d699a2889
commit 2e711e4d0d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=178913

View file

@ -1455,8 +1455,11 @@ kqueue_close(struct file *fp, struct thread *td)
for (i = 0; i < kq->kq_knlistsize; i++) {
while ((kn = SLIST_FIRST(&kq->kq_knlist[i])) != NULL) {
KASSERT((kn->kn_status & KN_INFLUX) == 0,
("KN_INFLUX set when not suppose to be"));
if ((kn->kn_status & KN_INFLUX) == KN_INFLUX) {
kq->kq_state |= KQ_FLUXWAIT;
msleep(kq, &kq->kq_lock, PSOCK, "kqclo1", 0);
continue;
}
kn->kn_status |= KN_INFLUX;
KQ_UNLOCK(kq);
if (!(kn->kn_status & KN_DETACHED))
@ -1468,8 +1471,12 @@ kqueue_close(struct file *fp, struct thread *td)
if (kq->kq_knhashmask != 0) {
for (i = 0; i <= kq->kq_knhashmask; i++) {
while ((kn = SLIST_FIRST(&kq->kq_knhash[i])) != NULL) {
KASSERT((kn->kn_status & KN_INFLUX) == 0,
("KN_INFLUX set when not suppose to be"));
if ((kn->kn_status & KN_INFLUX) == KN_INFLUX) {
kq->kq_state |= KQ_FLUXWAIT;
msleep(kq, &kq->kq_lock, PSOCK,
"kqclo2", 0);
continue;
}
kn->kn_status |= KN_INFLUX;
KQ_UNLOCK(kq);
if (!(kn->kn_status & KN_DETACHED))