summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_event.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-05-10 11:35:32 +0000
committerkib <kib@FreeBSD.org>2008-05-10 11:35:32 +0000
commit0f388c4977a67dd0f9ef74c78b2ce8af28a78eee (patch)
treee1cd90cc89e1032d8bf29d5615c8c11c090fce42 /sys/kern/kern_event.c
parent01a6de79b9702c2a686b2e018d436464a6ebd445 (diff)
downloadFreeBSD-src-0f388c4977a67dd0f9ef74c78b2ce8af28a78eee.zip
FreeBSD-src-0f388c4977a67dd0f9ef74c78b2ce8af28a78eee.tar.gz
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
Diffstat (limited to 'sys/kern/kern_event.c')
-rw-r--r--sys/kern/kern_event.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index d17a20d..ffd18d4 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -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))
OpenPOWER on IntegriCloud