Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109127007
D3307.id7872.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D3307.id7872.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D3307: Add support for anonymous kqueues.
Attached
Detach File
Event Timeline
Log In to Comment