Page MenuHomeFreeBSD

D3307.id7872.diff
No OneTemporary

D3307.id7872.diff

Index: head/sys/kern/kern_event.c
===================================================================
--- head/sys/kern/kern_event.c
+++ head/sys/kern/kern_event.c
@@ -99,6 +99,8 @@
struct thread *td, int waitok);
static int kqueue_acquire(struct file *fp, struct kqueue **kqp);
static void kqueue_release(struct kqueue *kq, int locked);
+static void kqueue_destroy(struct kqueue *kq);
+static void kqueue_drain(struct kqueue *kq, struct thread *td);
static int kqueue_expand(struct kqueue *kq, struct filterops *fops,
uintptr_t ident, int waitok);
static void kqueue_task(void *arg, int pending);
@@ -741,6 +743,16 @@
return (kern_kqueue(td, 0, NULL));
}
+static void
+kqueue_init(struct kqueue *kq)
+{
+
+ mtx_init(&kq->kq_lock, "kqueue", NULL, MTX_DEF | MTX_DUPOK);
+ TAILQ_INIT(&kq->kq_head);
+ knlist_init_mtx(&kq->kq_sel.si_note, &kq->kq_lock);
+ TASK_INIT(&kq->kq_task, 0, kqueue_task, kq);
+}
+
int
kern_kqueue(struct thread *td, int flags, struct filecaps *fcaps)
{
@@ -766,12 +778,9 @@
/* An extra reference on `fp' has been held for us by falloc(). */
kq = malloc(sizeof *kq, M_KQUEUE, M_WAITOK | M_ZERO);
- mtx_init(&kq->kq_lock, "kqueue", NULL, MTX_DEF|MTX_DUPOK);
- TAILQ_INIT(&kq->kq_head);
+ kqueue_init(kq);
kq->kq_fdp = fdp;
kq->kq_cred = cred;
- knlist_init_mtx(&kq->kq_sel.si_note, &kq->kq_lock);
- TASK_INIT(&kq->kq_task, 0, kqueue_task, kq);
FILEDESC_XLOCK(fdp);
TAILQ_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_list);
@@ -910,26 +919,20 @@
return (error);
}
-int
-kern_kevent_fp(struct thread *td, struct file *fp, int nchanges, int nevents,
+static int
+kqueue_kevent(struct kqueue *kq, struct thread *td, int nchanges, int nevents,
struct kevent_copyops *k_ops, const struct timespec *timeout)
{
struct kevent keva[KQ_NEVENTS];
struct kevent *kevp, *changes;
- struct kqueue *kq;
int i, n, nerrors, error;
- error = kqueue_acquire(fp, &kq);
- if (error != 0)
- return (error);
-
nerrors = 0;
-
while (nchanges > 0) {
n = nchanges > KQ_NEVENTS ? KQ_NEVENTS : nchanges;
error = k_ops->k_copyin(k_ops->arg, keva, n);
if (error)
- goto done;
+ return (error);
changes = keva;
for (i = 0; i < n; i++) {
kevp = &changes[i];
@@ -938,33 +941,56 @@
kevp->flags &= ~EV_SYSFLAGS;
error = kqueue_register(kq, kevp, td, 1);
if (error || (kevp->flags & EV_RECEIPT)) {
- if (nevents != 0) {
- kevp->flags = EV_ERROR;
- kevp->data = error;
- (void) k_ops->k_copyout(k_ops->arg,
- kevp, 1);
- nevents--;
- nerrors++;
- } else {
- goto done;
- }
+ if (nevents == 0)
+ return (error);
+ kevp->flags = EV_ERROR;
+ kevp->data = error;
+ (void)k_ops->k_copyout(k_ops->arg, kevp, 1);
+ nevents--;
+ nerrors++;
}
}
nchanges -= n;
}
if (nerrors) {
td->td_retval[0] = nerrors;
- error = 0;
- goto done;
+ return (0);
}
- error = kqueue_scan(kq, nevents, k_ops, timeout, keva, td);
-done:
+ return (kqueue_scan(kq, nevents, k_ops, timeout, keva, td));
+}
+
+int
+kern_kevent_fp(struct thread *td, struct file *fp, int nchanges, int nevents,
+ struct kevent_copyops *k_ops, const struct timespec *timeout)
+{
+ struct kqueue *kq;
+ int error;
+
+ error = kqueue_acquire(fp, &kq);
+ if (error != 0)
+ return (error);
+ error = kqueue_kevent(kq, td, nchanges, nevents, k_ops, timeout);
kqueue_release(kq, 0);
return (error);
}
int
+kern_kevent_anonymous(struct thread *td, int nevents,
+ struct kevent_copyops *k_ops)
+{
+ struct kqueue kq = {};
+ int error;
+
+ kqueue_init(&kq);
+ kq.kq_refcnt = 1;
+ error = kqueue_kevent(&kq, td, nevents, nevents, k_ops, NULL);
+ kqueue_drain(&kq, td);
+ kqueue_destroy(&kq);
+ return (error);
+}
+
+int
kqueue_add_filteropts(int filt, struct filterops *filtops)
{
int error;
@@ -1734,21 +1760,12 @@
return (0);
}
-/*ARGSUSED*/
-static int
-kqueue_close(struct file *fp, struct thread *td)
+static void
+kqueue_drain(struct kqueue *kq, struct thread *td)
{
- struct kqueue *kq = fp->f_data;
- struct filedesc *fdp;
struct knote *kn;
int i;
- int error;
- int filedesc_unlock;
-
- if ((error = kqueue_acquire(fp, &kq)))
- return error;
- filedesc_unlock = 0;
KQ_LOCK(kq);
KASSERT((kq->kq_state & KQ_CLOSING) != KQ_CLOSING,
@@ -1758,7 +1775,6 @@
msleep(&kq->kq_refcnt, &kq->kq_lock, PSOCK, "kqclose", 0);
KASSERT(kq->kq_refcnt == 1, ("other refs are out there!"));
- fdp = kq->kq_fdp;
KASSERT(knlist_empty(&kq->kq_sel.si_note),
("kqueue's knlist not empty"));
@@ -1809,6 +1825,36 @@
}
KQ_UNLOCK(kq);
+}
+
+static void
+kqueue_destroy(struct kqueue *kq)
+{
+
+ seldrain(&kq->kq_sel);
+ knlist_destroy(&kq->kq_sel.si_note);
+ mtx_destroy(&kq->kq_lock);
+
+ if (kq->kq_knhash != NULL)
+ free(kq->kq_knhash, M_KQUEUE);
+ if (kq->kq_knlist != NULL)
+ free(kq->kq_knlist, M_KQUEUE);
+
+ funsetown(&kq->kq_sigio);
+}
+
+/*ARGSUSED*/
+static int
+kqueue_close(struct file *fp, struct thread *td)
+{
+ struct kqueue *kq = fp->f_data;
+ struct filedesc *fdp;
+ int error;
+ int filedesc_unlock;
+
+ if ((error = kqueue_acquire(fp, &kq)))
+ return error;
+ kqueue_drain(kq, td);
/*
* We could be called due to the knote_drop() doing fdrop(),
@@ -1816,6 +1862,7 @@
* lock is owned, and filedesc sx is locked before, to not
* take the sleepable lock after non-sleepable.
*/
+ fdp = kq->kq_fdp;
if (!sx_xlocked(FILEDESC_LOCK(fdp))) {
FILEDESC_XLOCK(fdp);
filedesc_unlock = 1;
@@ -1825,17 +1872,7 @@
if (filedesc_unlock)
FILEDESC_XUNLOCK(fdp);
- seldrain(&kq->kq_sel);
- knlist_destroy(&kq->kq_sel.si_note);
- mtx_destroy(&kq->kq_lock);
- kq->kq_fdp = NULL;
-
- if (kq->kq_knhash != NULL)
- free(kq->kq_knhash, M_KQUEUE);
- if (kq->kq_knlist != NULL)
- free(kq->kq_knlist, M_KQUEUE);
-
- funsetown(&kq->kq_sigio);
+ kqueue_destroy(kq);
chgkqcnt(kq->kq_cred->cr_ruidinfo, -1, 0);
crfree(kq->kq_cred);
free(kq, M_KQUEUE);
Index: head/sys/sys/syscallsubr.h
===================================================================
--- head/sys/sys/syscallsubr.h
+++ head/sys/sys/syscallsubr.h
@@ -124,6 +124,8 @@
int kern_jail_set(struct thread *td, struct uio *options, int flags);
int kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
struct kevent_copyops *k_ops, const struct timespec *timeout);
+int kern_kevent_anonymous(struct thread *td, int nevents,
+ struct kevent_copyops *k_ops);
int kern_kevent_fp(struct thread *td, struct file *fp, int nchanges,
int nevents, struct kevent_copyops *k_ops,
const struct timespec *timeout);

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 2, 4:00 AM (20 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16395274
Default Alt Text
D3307.id7872.diff (6 KB)

Event Timeline