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);
 

Reply via email to