To prevent an infinite loop, threads looking for events inside
kqueue_scan(), insert a `marker' in the list.  Such markers are
not accounted and they are removed from the list as soon as the
thread is finished or goes to sleep.

Diff below is a small cleanup to keep the accounting of events in
sync with the number of events on the list.  This is a noop for the
moment, but it's small & easy part to review of my upcoming diff.

ok?

Index: kern/kern_event.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_event.c,v
retrieving revision 1.79
diff -u -p -r1.79 kern_event.c
--- kern/kern_event.c   31 May 2017 14:52:05 -0000      1.79
+++ kern/kern_event.c   9 Oct 2017 09:57:54 -0000
@@ -760,22 +760,24 @@ start:
        TAILQ_INSERT_TAIL(&kq->kq_head, &marker, kn_tqe);
        while (count) {
                kn = TAILQ_FIRST(&kq->kq_head);
-               TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe);
                if (kn == &marker) {
+                       TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe);
                        splx(s);
                        if (count == maxevents)
                                goto retry;
                        goto done;
                }
+
+               TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe);
+               kq->kq_count--;
+
                if (kn->kn_status & KN_DISABLED) {
                        kn->kn_status &= ~KN_QUEUED;
-                       kq->kq_count--;
                        continue;
                }
                if ((kn->kn_flags & EV_ONESHOT) == 0 &&
                    kn->kn_fop->f_event(kn, 0) == 0) {
                        kn->kn_status &= ~(KN_QUEUED | KN_ACTIVE);
-                       kq->kq_count--;
                        continue;
                }
                *kevp = kn->kn_kevent;
@@ -783,7 +785,6 @@ start:
                nkev++;
                if (kn->kn_flags & EV_ONESHOT) {
                        kn->kn_status &= ~KN_QUEUED;
-                       kq->kq_count--;
                        splx(s);
                        kn->kn_fop->f_detach(kn);
                        knote_drop(kn, p, p->p_fd);
@@ -796,9 +797,9 @@ start:
                        if (kn->kn_flags & EV_DISPATCH)
                                kn->kn_status |= KN_DISABLED;
                        kn->kn_status &= ~(KN_QUEUED | KN_ACTIVE);
-                       kq->kq_count--;
                } else {
                        TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe);
+                       kq->kq_count++;
                }
                count--;
                if (nkev == KQ_NEVENTS) {

Reply via email to