aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_event.c
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2017-01-02 01:23:21 +0000
committerMark Johnston <markj@FreeBSD.org>2017-01-02 01:23:21 +0000
commitb5442eba5cea37a73729514195b30c6410b6471e (patch)
tree33ed1edf264f1ce1759301b2c51a89fcf46d1e9d /sys/kern/kern_event.c
parent1248952a50b5a86b4b4e0a825f2e4d3c4426b8ce (diff)
Factor out instances of a knote detach followed by a knote_drop() call.
Reviewed by: kib (previous version) MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D9015
Notes
Notes: svn path=/head/; revision=311040
Diffstat (limited to 'sys/kern/kern_event.c')
-rw-r--r--sys/kern/kern_event.c37
1 files changed, 16 insertions, 21 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 0b862253039f..f9ee7b1103db 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -136,6 +136,7 @@ static struct fileops kqueueops = {
static int knote_attach(struct knote *kn, struct kqueue *kq);
static void knote_drop(struct knote *kn, struct thread *td);
+static void knote_drop_detached(struct knote *kn, struct thread *td);
static void knote_enqueue(struct knote *kn);
static void knote_dequeue(struct knote *kn);
static void knote_init(void);
@@ -1343,7 +1344,7 @@ findkn:
}
if ((error = kn->kn_fop->f_attach(kn)) != 0) {
- knote_drop(kn, td);
+ knote_drop_detached(kn, td);
goto done;
}
knl = kn_list_lock(kn);
@@ -1359,8 +1360,6 @@ findkn:
if (kev->flags & EV_DELETE) {
kn_enter_flux(kn);
KQ_UNLOCK(kq);
- if (!(kn->kn_status & KN_DETACHED))
- kn->kn_fop->f_detach(kn);
knote_drop(kn, td);
goto done;
}
@@ -1684,8 +1683,6 @@ retry:
* We don't need to lock the list since we've
* marked it as in flux.
*/
- if (!(kn->kn_status & KN_DETACHED))
- kn->kn_fop->f_detach(kn);
knote_drop(kn, td);
KQ_LOCK(kq);
continue;
@@ -1699,8 +1696,6 @@ retry:
* marked the knote as being in flux.
*/
*kevp = kn->kn_kevent;
- if (!(kn->kn_status & KN_DETACHED))
- kn->kn_fop->f_detach(kn);
knote_drop(kn, td);
KQ_LOCK(kq);
kn = NULL;
@@ -1902,8 +1897,6 @@ kqueue_drain(struct kqueue *kq, struct thread *td)
}
kn_enter_flux(kn);
KQ_UNLOCK(kq);
- if (!(kn->kn_status & KN_DETACHED))
- kn->kn_fop->f_detach(kn);
knote_drop(kn, td);
KQ_LOCK(kq);
}
@@ -1919,8 +1912,6 @@ kqueue_drain(struct kqueue *kq, struct thread *td)
}
kn_enter_flux(kn);
KQ_UNLOCK(kq);
- if (!(kn->kn_status & KN_DETACHED))
- kn->kn_fop->f_detach(kn);
knote_drop(kn, td);
KQ_LOCK(kq);
}
@@ -2323,10 +2314,9 @@ again: /* need to reacquire lock since we have dropped it */
}
knlist_remove_kq(knl, kn, 1, 1);
if (killkn) {
- kn->kn_status |= KN_DETACHED;
kn_enter_flux(kn);
KQ_UNLOCK(kq);
- knote_drop(kn, td);
+ knote_drop_detached(kn, td);
} else {
/* Make sure cleared knotes disappear soon */
kn->kn_flags |= EV_EOF | EV_ONESHOT;
@@ -2392,10 +2382,8 @@ again:
}
kn_enter_flux(kn);
KQ_UNLOCK(kq);
- if (!(kn->kn_status & KN_DETACHED))
- kn->kn_fop->f_detach(kn);
- knote_drop(kn, td);
influx = 1;
+ knote_drop(kn, td);
KQ_LOCK(kq);
}
KQ_UNLOCK_FLUX(kq);
@@ -2423,20 +2411,27 @@ knote_attach(struct knote *kn, struct kqueue *kq)
return (0);
}
-/*
- * knote must already have been detached using the f_detach method.
- * no lock need to be held, it is assumed that the influx state is set
- * to prevent other removal.
- */
static void
knote_drop(struct knote *kn, struct thread *td)
{
+
+ if ((kn->kn_status & KN_DETACHED) == 0)
+ kn->kn_fop->f_detach(kn);
+ knote_drop_detached(kn, td);
+}
+
+static void
+knote_drop_detached(struct knote *kn, struct thread *td)
+{
struct kqueue *kq;
struct klist *list;
kq = kn->kn_kq;
+ KASSERT((kn->kn_status & KN_DETACHED) != 0,
+ ("knote %p still attached", kn));
KQ_NOTOWNED(kq);
+
KQ_LOCK(kq);
KASSERT(kn->kn_influx == 1,
("knote_drop called on %p with influx %d", kn, kn->kn_influx));