Small refactoring needed to manage per-thread kqueues. Such kqueue are
not associated to a file descriptor, that's why the functions below take
a "struct kqueue *" as argument.
ok?
Index: kern/kern_event.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_event.c,v
retrieving revision 1.132
diff -u -p -r1.132 kern_event.c
--- kern/kern_event.c 17 May 2020 10:53:14 -0000 1.132
+++ kern/kern_event.c 25 May 2020 11:24:03 -0000
@@ -57,6 +57,8 @@
#include <sys/timeout.h>
#include <sys/wait.h>
+void kqueue_terminate(struct proc *p, struct kqueue *);
+void kqueue_free(struct kqueue *);
void kqueue_init(void);
void KQREF(struct kqueue *);
void KQRELE(struct kqueue *);
@@ -181,8 +183,13 @@ KQRELE(struct kqueue *kq)
fdpunlock(fdp);
}
- free(kq->kq_knlist, M_KEVENT, kq->kq_knlistsize *
- sizeof(struct knlist));
+ kqueue_free(kq);
+}
+
+void
+kqueue_free(struct kqueue *kq)
+{
+ free(kq->kq_knlist, M_KEVENT, kq->kq_knlistsize * sizeof(struct klist));
hashfree(kq->kq_knhash, KN_HASHSIZE, M_KEVENT);
pool_put(&kqueue_pool, kq);
}
@@ -492,13 +499,10 @@ static const struct filterops dead_filto
.f_event = filt_dead,
};
-int
-sys_kqueue(struct proc *p, void *v, register_t *retval)
+struct kqueue *
+kqueue_alloc(struct filedesc *fdp)
{
- struct filedesc *fdp = p->p_fd;
struct kqueue *kq;
- struct file *fp;
- int fd, error;
kq = pool_get(&kqueue_pool, PR_WAITOK | PR_ZERO);
kq->kq_refs = 1;
@@ -506,6 +510,19 @@ sys_kqueue(struct proc *p, void *v, regi
TAILQ_INIT(&kq->kq_head);
task_set(&kq->kq_task, kqueue_task, kq);
+ return (kq);
+}
+
+int
+sys_kqueue(struct proc *p, void *v, register_t *retval)
+{
+ struct filedesc *fdp = p->p_fd;
+ struct kqueue *kq;
+ struct file *fp;
+ int fd, error;
+
+ kq = kqueue_alloc(fdp);
+
fdplock(fdp);
error = falloc(p, &fp, &fd);
if (error)
@@ -1115,13 +1132,12 @@ kqueue_stat(struct file *fp, struct stat
return (0);
}
-int
-kqueue_close(struct file *fp, struct proc *p)
+void
+kqueue_terminate(struct proc *p, struct kqueue *kq)
{
- struct kqueue *kq = fp->f_data;
int i;
- KERNEL_LOCK();
+ KERNEL_ASSERT_LOCKED();
for (i = 0; i < kq->kq_knlistsize; i++)
knote_remove(p, &kq->kq_knlist[i]);
@@ -1129,13 +1145,22 @@ kqueue_close(struct file *fp, struct pro
for (i = 0; i < kq->kq_knhashmask + 1; i++)
knote_remove(p, &kq->kq_knhash[i]);
}
- fp->f_data = NULL;
-
kq->kq_state |= KQ_DYING;
kqueue_wakeup(kq);
KASSERT(klist_empty(&kq->kq_sel.si_note));
task_del(systq, &kq->kq_task);
+
+}
+
+int
+kqueue_close(struct file *fp, struct proc *p)
+{
+ struct kqueue *kq = fp->f_data;
+
+ KERNEL_LOCK();
+ kqueue_terminate(p, kq);
+ fp->f_data = NULL;
KQRELE(kq);