kern_event.c revision 1.36 1 /* $NetBSD: kern_event.c,v 1.36 2007/02/17 22:31:42 pavel Exp $ */
2
3 /*-
4 * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon (at) FreeBSD.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD: src/sys/kern/kern_event.c,v 1.27 2001/07/05 17:10:44 rwatson Exp $
29 */
30
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.36 2007/02/17 22:31:42 pavel Exp $");
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/proc.h>
38 #include <sys/malloc.h>
39 #include <sys/unistd.h>
40 #include <sys/file.h>
41 #include <sys/fcntl.h>
42 #include <sys/select.h>
43 #include <sys/queue.h>
44 #include <sys/event.h>
45 #include <sys/eventvar.h>
46 #include <sys/poll.h>
47 #include <sys/pool.h>
48 #include <sys/protosw.h>
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
51 #include <sys/stat.h>
52 #include <sys/uio.h>
53 #include <sys/mount.h>
54 #include <sys/filedesc.h>
55 #include <sys/syscallargs.h>
56 #include <sys/kauth.h>
57
58 static void kqueue_wakeup(struct kqueue *kq);
59
60 static int kqueue_scan(struct file *, size_t, struct kevent *,
61 const struct timespec *, struct lwp *, register_t *,
62 const struct kevent_ops *);
63 static int kqueue_read(struct file *fp, off_t *offset, struct uio *uio,
64 kauth_cred_t cred, int flags);
65 static int kqueue_write(struct file *fp, off_t *offset, struct uio *uio,
66 kauth_cred_t cred, int flags);
67 static int kqueue_ioctl(struct file *fp, u_long com, void *data,
68 struct lwp *l);
69 static int kqueue_fcntl(struct file *fp, u_int com, void *data,
70 struct lwp *l);
71 static int kqueue_poll(struct file *fp, int events, struct lwp *l);
72 static int kqueue_kqfilter(struct file *fp, struct knote *kn);
73 static int kqueue_stat(struct file *fp, struct stat *sp, struct lwp *l);
74 static int kqueue_close(struct file *fp, struct lwp *l);
75
76 static const struct fileops kqueueops = {
77 kqueue_read, kqueue_write, kqueue_ioctl, kqueue_fcntl, kqueue_poll,
78 kqueue_stat, kqueue_close, kqueue_kqfilter
79 };
80
81 static void knote_attach(struct knote *kn, struct filedesc *fdp);
82 static void knote_drop(struct knote *kn, struct lwp *l,
83 struct filedesc *fdp);
84 static void knote_enqueue(struct knote *kn);
85 static void knote_dequeue(struct knote *kn);
86
87 static void filt_kqdetach(struct knote *kn);
88 static int filt_kqueue(struct knote *kn, long hint);
89 static int filt_procattach(struct knote *kn);
90 static void filt_procdetach(struct knote *kn);
91 static int filt_proc(struct knote *kn, long hint);
92 static int filt_fileattach(struct knote *kn);
93 static void filt_timerexpire(void *knx);
94 static int filt_timerattach(struct knote *kn);
95 static void filt_timerdetach(struct knote *kn);
96 static int filt_timer(struct knote *kn, long hint);
97
98 static const struct filterops kqread_filtops =
99 { 1, NULL, filt_kqdetach, filt_kqueue };
100 static const struct filterops proc_filtops =
101 { 0, filt_procattach, filt_procdetach, filt_proc };
102 static const struct filterops file_filtops =
103 { 1, filt_fileattach, NULL, NULL };
104 static const struct filterops timer_filtops =
105 { 0, filt_timerattach, filt_timerdetach, filt_timer };
106
107 static POOL_INIT(kqueue_pool, sizeof(struct kqueue), 0, 0, 0, "kqueuepl", NULL);
108 static POOL_INIT(knote_pool, sizeof(struct knote), 0, 0, 0, "knotepl", NULL);
109 static int kq_ncallouts = 0;
110 static int kq_calloutmax = (4 * 1024);
111
112 MALLOC_DEFINE(M_KEVENT, "kevent", "kevents/knotes");
113
114 #define KNOTE_ACTIVATE(kn) \
115 do { \
116 kn->kn_status |= KN_ACTIVE; \
117 if ((kn->kn_status & (KN_QUEUED | KN_DISABLED)) == 0) \
118 knote_enqueue(kn); \
119 } while(0)
120
121 #define KN_HASHSIZE 64 /* XXX should be tunable */
122 #define KN_HASH(val, mask) (((val) ^ (val >> 8)) & (mask))
123
124 extern const struct filterops sig_filtops;
125
126 /*
127 * Table for for all system-defined filters.
128 * These should be listed in the numeric order of the EVFILT_* defines.
129 * If filtops is NULL, the filter isn't implemented in NetBSD.
130 * End of list is when name is NULL.
131 */
132 struct kfilter {
133 const char *name; /* name of filter */
134 uint32_t filter; /* id of filter */
135 const struct filterops *filtops;/* operations for filter */
136 };
137
138 /* System defined filters */
139 static const struct kfilter sys_kfilters[] = {
140 { "EVFILT_READ", EVFILT_READ, &file_filtops },
141 { "EVFILT_WRITE", EVFILT_WRITE, &file_filtops },
142 { "EVFILT_AIO", EVFILT_AIO, NULL },
143 { "EVFILT_VNODE", EVFILT_VNODE, &file_filtops },
144 { "EVFILT_PROC", EVFILT_PROC, &proc_filtops },
145 { "EVFILT_SIGNAL", EVFILT_SIGNAL, &sig_filtops },
146 { "EVFILT_TIMER", EVFILT_TIMER, &timer_filtops },
147 { NULL, 0, NULL }, /* end of list */
148 };
149
150 /* User defined kfilters */
151 static struct kfilter *user_kfilters; /* array */
152 static int user_kfilterc; /* current offset */
153 static int user_kfiltermaxc; /* max size so far */
154
155 /*
156 * Find kfilter entry by name, or NULL if not found.
157 */
158 static const struct kfilter *
159 kfilter_byname_sys(const char *name)
160 {
161 int i;
162
163 for (i = 0; sys_kfilters[i].name != NULL; i++) {
164 if (strcmp(name, sys_kfilters[i].name) == 0)
165 return (&sys_kfilters[i]);
166 }
167 return (NULL);
168 }
169
170 static struct kfilter *
171 kfilter_byname_user(const char *name)
172 {
173 int i;
174
175 /* user filter slots have a NULL name if previously deregistered */
176 for (i = 0; i < user_kfilterc ; i++) {
177 if (user_kfilters[i].name != NULL &&
178 strcmp(name, user_kfilters[i].name) == 0)
179 return (&user_kfilters[i]);
180 }
181 return (NULL);
182 }
183
184 static const struct kfilter *
185 kfilter_byname(const char *name)
186 {
187 const struct kfilter *kfilter;
188
189 if ((kfilter = kfilter_byname_sys(name)) != NULL)
190 return (kfilter);
191
192 return (kfilter_byname_user(name));
193 }
194
195 /*
196 * Find kfilter entry by filter id, or NULL if not found.
197 * Assumes entries are indexed in filter id order, for speed.
198 */
199 static const struct kfilter *
200 kfilter_byfilter(uint32_t filter)
201 {
202 const struct kfilter *kfilter;
203
204 if (filter < EVFILT_SYSCOUNT) /* it's a system filter */
205 kfilter = &sys_kfilters[filter];
206 else if (user_kfilters != NULL &&
207 filter < EVFILT_SYSCOUNT + user_kfilterc)
208 /* it's a user filter */
209 kfilter = &user_kfilters[filter - EVFILT_SYSCOUNT];
210 else
211 return (NULL); /* out of range */
212 KASSERT(kfilter->filter == filter); /* sanity check! */
213 return (kfilter);
214 }
215
216 /*
217 * Register a new kfilter. Stores the entry in user_kfilters.
218 * Returns 0 if operation succeeded, or an appropriate errno(2) otherwise.
219 * If retfilter != NULL, the new filterid is returned in it.
220 */
221 int
222 kfilter_register(const char *name, const struct filterops *filtops,
223 int *retfilter)
224 {
225 struct kfilter *kfilter;
226 void *space;
227 int len;
228 int i;
229
230 if (name == NULL || name[0] == '\0' || filtops == NULL)
231 return (EINVAL); /* invalid args */
232 if (kfilter_byname(name) != NULL)
233 return (EEXIST); /* already exists */
234 if (user_kfilterc > 0xffffffff - EVFILT_SYSCOUNT)
235 return (EINVAL); /* too many */
236
237 for (i = 0; i < user_kfilterc; i++) {
238 kfilter = &user_kfilters[i];
239 if (kfilter->name == NULL) {
240 /* Previously deregistered slot. Reuse. */
241 goto reuse;
242 }
243 }
244
245 /* check if need to grow user_kfilters */
246 if (user_kfilterc + 1 > user_kfiltermaxc) {
247 /*
248 * Grow in KFILTER_EXTENT chunks. Use malloc(9), because we
249 * want to traverse user_kfilters as an array.
250 */
251 user_kfiltermaxc += KFILTER_EXTENT;
252 kfilter = malloc(user_kfiltermaxc * sizeof(struct filter *),
253 M_KEVENT, M_WAITOK);
254
255 /* copy existing user_kfilters */
256 if (user_kfilters != NULL)
257 memcpy((caddr_t)kfilter, (caddr_t)user_kfilters,
258 user_kfilterc * sizeof(struct kfilter *));
259 /* zero new sections */
260 memset((caddr_t)kfilter +
261 user_kfilterc * sizeof(struct kfilter *), 0,
262 (user_kfiltermaxc - user_kfilterc) *
263 sizeof(struct kfilter *));
264 /* switch to new kfilter */
265 if (user_kfilters != NULL)
266 free(user_kfilters, M_KEVENT);
267 user_kfilters = kfilter;
268 }
269 /* Adding new slot */
270 kfilter = &user_kfilters[user_kfilterc++];
271 reuse:
272 len = strlen(name) + 1; /* copy name */
273 space = malloc(len, M_KEVENT, M_WAITOK);
274 memcpy(space, name, len);
275 kfilter->name = space;
276
277 kfilter->filter = (kfilter - user_kfilters) + EVFILT_SYSCOUNT;
278
279 len = sizeof(struct filterops); /* copy filtops */
280 space = malloc(len, M_KEVENT, M_WAITOK);
281 memcpy(space, filtops, len);
282 kfilter->filtops = space;
283
284 if (retfilter != NULL)
285 *retfilter = kfilter->filter;
286 return (0);
287 }
288
289 /*
290 * Unregister a kfilter previously registered with kfilter_register.
291 * This retains the filter id, but clears the name and frees filtops (filter
292 * operations), so that the number isn't reused during a boot.
293 * Returns 0 if operation succeeded, or an appropriate errno(2) otherwise.
294 */
295 int
296 kfilter_unregister(const char *name)
297 {
298 struct kfilter *kfilter;
299
300 if (name == NULL || name[0] == '\0')
301 return (EINVAL); /* invalid name */
302
303 if (kfilter_byname_sys(name) != NULL)
304 return (EINVAL); /* can't detach system filters */
305
306 kfilter = kfilter_byname_user(name);
307 if (kfilter == NULL) /* not found */
308 return (ENOENT);
309
310 /* XXXUNCONST Cast away const (but we know it's safe. */
311 free(__UNCONST(kfilter->name), M_KEVENT);
312 kfilter->name = NULL; /* mark as `not implemented' */
313
314 if (kfilter->filtops != NULL) {
315 /* XXXUNCONST Cast away const (but we know it's safe. */
316 free(__UNCONST(kfilter->filtops), M_KEVENT);
317 kfilter->filtops = NULL; /* mark as `not implemented' */
318 }
319 return (0);
320 }
321
322
323 /*
324 * Filter attach method for EVFILT_READ and EVFILT_WRITE on normal file
325 * descriptors. Calls struct fileops kqfilter method for given file descriptor.
326 */
327 static int
328 filt_fileattach(struct knote *kn)
329 {
330 struct file *fp;
331
332 fp = kn->kn_fp;
333 return ((*fp->f_ops->fo_kqfilter)(fp, kn));
334 }
335
336 /*
337 * Filter detach method for EVFILT_READ on kqueue descriptor.
338 */
339 static void
340 filt_kqdetach(struct knote *kn)
341 {
342 struct kqueue *kq;
343
344 kq = (struct kqueue *)kn->kn_fp->f_data;
345 SLIST_REMOVE(&kq->kq_sel.sel_klist, kn, knote, kn_selnext);
346 }
347
348 /*
349 * Filter event method for EVFILT_READ on kqueue descriptor.
350 */
351 /*ARGSUSED*/
352 static int
353 filt_kqueue(struct knote *kn, long hint)
354 {
355 struct kqueue *kq;
356
357 kq = (struct kqueue *)kn->kn_fp->f_data;
358 kn->kn_data = kq->kq_count;
359 return (kn->kn_data > 0);
360 }
361
362 /*
363 * Filter attach method for EVFILT_PROC.
364 */
365 static int
366 filt_procattach(struct knote *kn)
367 {
368 struct proc *p, *curp;
369 struct lwp *curl;
370
371 curl = curlwp;
372 curp = curl->l_proc;
373
374 p = pfind(kn->kn_id);
375 if (p == NULL)
376 return (ESRCH);
377
378 /*
379 * Fail if it's not owned by you, or the last exec gave us
380 * setuid/setgid privs (unless you're root).
381 */
382 if ((kauth_cred_getuid(p->p_cred) != kauth_cred_getuid(curl->l_cred) ||
383 (p->p_flag & PK_SUGID)) && kauth_authorize_generic(curl->l_cred,
384 KAUTH_GENERIC_ISSUSER, NULL) != 0)
385 return (EACCES);
386
387 kn->kn_ptr.p_proc = p;
388 kn->kn_flags |= EV_CLEAR; /* automatically set */
389
390 /*
391 * internal flag indicating registration done by kernel
392 */
393 if (kn->kn_flags & EV_FLAG1) {
394 kn->kn_data = kn->kn_sdata; /* ppid */
395 kn->kn_fflags = NOTE_CHILD;
396 kn->kn_flags &= ~EV_FLAG1;
397 }
398
399 /* XXXSMP lock the process? */
400 SLIST_INSERT_HEAD(&p->p_klist, kn, kn_selnext);
401
402 return (0);
403 }
404
405 /*
406 * Filter detach method for EVFILT_PROC.
407 *
408 * The knote may be attached to a different process, which may exit,
409 * leaving nothing for the knote to be attached to. So when the process
410 * exits, the knote is marked as DETACHED and also flagged as ONESHOT so
411 * it will be deleted when read out. However, as part of the knote deletion,
412 * this routine is called, so a check is needed to avoid actually performing
413 * a detach, because the original process might not exist any more.
414 */
415 static void
416 filt_procdetach(struct knote *kn)
417 {
418 struct proc *p;
419
420 if (kn->kn_status & KN_DETACHED)
421 return;
422
423 p = kn->kn_ptr.p_proc;
424
425 /* XXXSMP lock the process? */
426 SLIST_REMOVE(&p->p_klist, kn, knote, kn_selnext);
427 }
428
429 /*
430 * Filter event method for EVFILT_PROC.
431 */
432 static int
433 filt_proc(struct knote *kn, long hint)
434 {
435 u_int event;
436
437 /*
438 * mask off extra data
439 */
440 event = (u_int)hint & NOTE_PCTRLMASK;
441
442 /*
443 * if the user is interested in this event, record it.
444 */
445 if (kn->kn_sfflags & event)
446 kn->kn_fflags |= event;
447
448 /*
449 * process is gone, so flag the event as finished.
450 */
451 if (event == NOTE_EXIT) {
452 /*
453 * Detach the knote from watched process and mark
454 * it as such. We can't leave this to kqueue_scan(),
455 * since the process might not exist by then. And we
456 * have to do this now, since psignal KNOTE() is called
457 * also for zombies and we might end up reading freed
458 * memory if the kevent would already be picked up
459 * and knote g/c'ed.
460 */
461 kn->kn_fop->f_detach(kn);
462 kn->kn_status |= KN_DETACHED;
463
464 /* Mark as ONESHOT, so that the knote it g/c'ed when read */
465 kn->kn_flags |= (EV_EOF | EV_ONESHOT);
466 return (1);
467 }
468
469 /*
470 * process forked, and user wants to track the new process,
471 * so attach a new knote to it, and immediately report an
472 * event with the parent's pid.
473 */
474 if ((event == NOTE_FORK) && (kn->kn_sfflags & NOTE_TRACK)) {
475 struct kevent kev;
476 int error;
477
478 /*
479 * register knote with new process.
480 */
481 kev.ident = hint & NOTE_PDATAMASK; /* pid */
482 kev.filter = kn->kn_filter;
483 kev.flags = kn->kn_flags | EV_ADD | EV_ENABLE | EV_FLAG1;
484 kev.fflags = kn->kn_sfflags;
485 kev.data = kn->kn_id; /* parent */
486 kev.udata = kn->kn_kevent.udata; /* preserve udata */
487 error = kqueue_register(kn->kn_kq, &kev, NULL);
488 if (error)
489 kn->kn_fflags |= NOTE_TRACKERR;
490 }
491
492 return (kn->kn_fflags != 0);
493 }
494
495 static void
496 filt_timerexpire(void *knx)
497 {
498 struct knote *kn = knx;
499 int tticks;
500
501 kn->kn_data++;
502 KNOTE_ACTIVATE(kn);
503
504 if ((kn->kn_flags & EV_ONESHOT) == 0) {
505 tticks = mstohz(kn->kn_sdata);
506 callout_schedule((struct callout *)kn->kn_hook, tticks);
507 }
508 }
509
510 /*
511 * data contains amount of time to sleep, in milliseconds
512 */
513 static int
514 filt_timerattach(struct knote *kn)
515 {
516 struct callout *calloutp;
517 int tticks;
518
519 if (kq_ncallouts >= kq_calloutmax)
520 return (ENOMEM);
521 kq_ncallouts++;
522
523 tticks = mstohz(kn->kn_sdata);
524
525 /* if the supplied value is under our resolution, use 1 tick */
526 if (tticks == 0) {
527 if (kn->kn_sdata == 0)
528 return (EINVAL);
529 tticks = 1;
530 }
531
532 kn->kn_flags |= EV_CLEAR; /* automatically set */
533 MALLOC(calloutp, struct callout *, sizeof(*calloutp),
534 M_KEVENT, 0);
535 callout_init(calloutp);
536 callout_reset(calloutp, tticks, filt_timerexpire, kn);
537 kn->kn_hook = calloutp;
538
539 return (0);
540 }
541
542 static void
543 filt_timerdetach(struct knote *kn)
544 {
545 struct callout *calloutp;
546
547 calloutp = (struct callout *)kn->kn_hook;
548 callout_stop(calloutp);
549 FREE(calloutp, M_KEVENT);
550 kq_ncallouts--;
551 }
552
553 static int
554 filt_timer(struct knote *kn, long hint)
555 {
556 return (kn->kn_data != 0);
557 }
558
559 /*
560 * filt_seltrue:
561 *
562 * This filter "event" routine simulates seltrue().
563 */
564 int
565 filt_seltrue(struct knote *kn, long hint)
566 {
567
568 /*
569 * We don't know how much data can be read/written,
570 * but we know that it *can* be. This is about as
571 * good as select/poll does as well.
572 */
573 kn->kn_data = 0;
574 return (1);
575 }
576
577 /*
578 * This provides full kqfilter entry for device switch tables, which
579 * has same effect as filter using filt_seltrue() as filter method.
580 */
581 static void
582 filt_seltruedetach(struct knote *kn)
583 {
584 /* Nothing to do */
585 }
586
587 static const struct filterops seltrue_filtops =
588 { 1, NULL, filt_seltruedetach, filt_seltrue };
589
590 int
591 seltrue_kqfilter(dev_t dev, struct knote *kn)
592 {
593 switch (kn->kn_filter) {
594 case EVFILT_READ:
595 case EVFILT_WRITE:
596 kn->kn_fop = &seltrue_filtops;
597 break;
598 default:
599 return (1);
600 }
601
602 /* Nothing more to do */
603 return (0);
604 }
605
606 /*
607 * kqueue(2) system call.
608 */
609 int
610 sys_kqueue(struct lwp *l, void *v, register_t *retval)
611 {
612 struct filedesc *fdp;
613 struct kqueue *kq;
614 struct file *fp;
615 int fd, error;
616
617 fdp = l->l_proc->p_fd;
618 error = falloc(l, &fp, &fd); /* setup a new file descriptor */
619 if (error)
620 return (error);
621 fp->f_flag = FREAD | FWRITE;
622 fp->f_type = DTYPE_KQUEUE;
623 fp->f_ops = &kqueueops;
624 kq = pool_get(&kqueue_pool, PR_WAITOK);
625 memset((char *)kq, 0, sizeof(struct kqueue));
626 simple_lock_init(&kq->kq_lock);
627 TAILQ_INIT(&kq->kq_head);
628 fp->f_data = (caddr_t)kq; /* store the kqueue with the fp */
629 *retval = fd;
630 if (fdp->fd_knlistsize < 0)
631 fdp->fd_knlistsize = 0; /* this process has a kq */
632 kq->kq_fdp = fdp;
633 FILE_SET_MATURE(fp);
634 FILE_UNUSE(fp, l); /* falloc() does FILE_USE() */
635 return (error);
636 }
637
638 /*
639 * kevent(2) system call.
640 */
641 static int
642 kevent_fetch_changes(void *private, const struct kevent *changelist,
643 struct kevent *changes, size_t index, int n)
644 {
645 return copyin(changelist + index, changes, n * sizeof(*changes));
646 }
647
648 static int
649 kevent_put_events(void *private, struct kevent *events,
650 struct kevent *eventlist, size_t index, int n)
651 {
652 return copyout(events, eventlist + index, n * sizeof(*events));
653 }
654
655 static const struct kevent_ops kevent_native_ops = {
656 keo_private: NULL,
657 keo_fetch_timeout: copyin,
658 keo_fetch_changes: kevent_fetch_changes,
659 keo_put_events: kevent_put_events,
660 };
661
662 int
663 sys_kevent(struct lwp *l, void *v, register_t *retval)
664 {
665 struct sys_kevent_args /* {
666 syscallarg(int) fd;
667 syscallarg(const struct kevent *) changelist;
668 syscallarg(size_t) nchanges;
669 syscallarg(struct kevent *) eventlist;
670 syscallarg(size_t) nevents;
671 syscallarg(const struct timespec *) timeout;
672 } */ *uap = v;
673
674 return kevent1(l, retval, SCARG(uap, fd), SCARG(uap, changelist),
675 SCARG(uap, nchanges), SCARG(uap, eventlist), SCARG(uap, nevents),
676 SCARG(uap, timeout), &kevent_native_ops);
677 }
678
679 int
680 kevent1(struct lwp *l, register_t *retval, int fd,
681 const struct kevent *changelist, size_t nchanges, struct kevent *eventlist,
682 size_t nevents, const struct timespec *timeout,
683 const struct kevent_ops *keops)
684 {
685 struct kevent *kevp;
686 struct kqueue *kq;
687 struct file *fp;
688 struct timespec ts;
689 struct proc *p;
690 size_t i, n, ichange;
691 int nerrors, error;
692
693 p = l->l_proc;
694 /* check that we're dealing with a kq */
695 fp = fd_getfile(p->p_fd, fd);
696 if (fp == NULL)
697 return (EBADF);
698
699 if (fp->f_type != DTYPE_KQUEUE) {
700 simple_unlock(&fp->f_slock);
701 return (EBADF);
702 }
703
704 FILE_USE(fp);
705
706 if (timeout != NULL) {
707 error = (*keops->keo_fetch_timeout)(timeout, &ts, sizeof(ts));
708 if (error)
709 goto done;
710 timeout = &ts;
711 }
712
713 kq = (struct kqueue *)fp->f_data;
714 nerrors = 0;
715 ichange = 0;
716
717 /* traverse list of events to register */
718 while (nchanges > 0) {
719 /* copyin a maximum of KQ_EVENTS at each pass */
720 n = MIN(nchanges, KQ_NEVENTS);
721 error = (*keops->keo_fetch_changes)(keops->keo_private,
722 changelist, kq->kq_kev, ichange, n);
723 if (error)
724 goto done;
725 for (i = 0; i < n; i++) {
726 kevp = &kq->kq_kev[i];
727 kevp->flags &= ~EV_SYSFLAGS;
728 /* register each knote */
729 error = kqueue_register(kq, kevp, l);
730 if (error) {
731 if (nevents != 0) {
732 kevp->flags = EV_ERROR;
733 kevp->data = error;
734 error = (*keops->keo_put_events)
735 (keops->keo_private, kevp,
736 eventlist, nerrors, 1);
737 if (error)
738 goto done;
739 nevents--;
740 nerrors++;
741 } else {
742 goto done;
743 }
744 }
745 }
746 nchanges -= n; /* update the results */
747 ichange += n;
748 }
749 if (nerrors) {
750 *retval = nerrors;
751 error = 0;
752 goto done;
753 }
754
755 /* actually scan through the events */
756 error = kqueue_scan(fp, nevents, eventlist, timeout, l, retval, keops);
757 done:
758 FILE_UNUSE(fp, l);
759 return (error);
760 }
761
762 /*
763 * Register a given kevent kev onto the kqueue
764 */
765 int
766 kqueue_register(struct kqueue *kq, struct kevent *kev, struct lwp *l)
767 {
768 const struct kfilter *kfilter;
769 struct filedesc *fdp;
770 struct file *fp;
771 struct knote *kn;
772 int s, error;
773
774 fdp = kq->kq_fdp;
775 fp = NULL;
776 kn = NULL;
777 error = 0;
778 kfilter = kfilter_byfilter(kev->filter);
779 if (kfilter == NULL || kfilter->filtops == NULL) {
780 /* filter not found nor implemented */
781 return (EINVAL);
782 }
783
784 /* search if knote already exists */
785 if (kfilter->filtops->f_isfd) {
786 /* monitoring a file descriptor */
787 if ((fp = fd_getfile(fdp, kev->ident)) == NULL)
788 return (EBADF); /* validate descriptor */
789 FILE_USE(fp);
790
791 if (kev->ident < fdp->fd_knlistsize) {
792 SLIST_FOREACH(kn, &fdp->fd_knlist[kev->ident], kn_link)
793 if (kq == kn->kn_kq &&
794 kev->filter == kn->kn_filter)
795 break;
796 }
797 } else {
798 /*
799 * not monitoring a file descriptor, so
800 * lookup knotes in internal hash table
801 */
802 if (fdp->fd_knhashmask != 0) {
803 struct klist *list;
804
805 list = &fdp->fd_knhash[
806 KN_HASH((u_long)kev->ident, fdp->fd_knhashmask)];
807 SLIST_FOREACH(kn, list, kn_link)
808 if (kev->ident == kn->kn_id &&
809 kq == kn->kn_kq &&
810 kev->filter == kn->kn_filter)
811 break;
812 }
813 }
814
815 if (kn == NULL && ((kev->flags & EV_ADD) == 0)) {
816 error = ENOENT; /* filter not found */
817 goto done;
818 }
819
820 /*
821 * kn now contains the matching knote, or NULL if no match
822 */
823 if (kev->flags & EV_ADD) {
824 /* add knote */
825
826 if (kn == NULL) {
827 /* create new knote */
828 kn = pool_get(&knote_pool, PR_WAITOK);
829 if (kn == NULL) {
830 error = ENOMEM;
831 goto done;
832 }
833 kn->kn_fp = fp;
834 kn->kn_kq = kq;
835 kn->kn_fop = kfilter->filtops;
836
837 /*
838 * apply reference count to knote structure, and
839 * do not release it at the end of this routine.
840 */
841 fp = NULL;
842
843 kn->kn_sfflags = kev->fflags;
844 kn->kn_sdata = kev->data;
845 kev->fflags = 0;
846 kev->data = 0;
847 kn->kn_kevent = *kev;
848
849 knote_attach(kn, fdp);
850 if ((error = kfilter->filtops->f_attach(kn)) != 0) {
851 knote_drop(kn, l, fdp);
852 goto done;
853 }
854 } else {
855 /* modify existing knote */
856
857 /*
858 * The user may change some filter values after the
859 * initial EV_ADD, but doing so will not reset any
860 * filter which have already been triggered.
861 */
862 kn->kn_sfflags = kev->fflags;
863 kn->kn_sdata = kev->data;
864 kn->kn_kevent.udata = kev->udata;
865 }
866
867 s = splsched();
868 if (kn->kn_fop->f_event(kn, 0))
869 KNOTE_ACTIVATE(kn);
870 splx(s);
871
872 } else if (kev->flags & EV_DELETE) { /* delete knote */
873 kn->kn_fop->f_detach(kn);
874 knote_drop(kn, l, fdp);
875 goto done;
876 }
877
878 /* disable knote */
879 if ((kev->flags & EV_DISABLE) &&
880 ((kn->kn_status & KN_DISABLED) == 0)) {
881 s = splsched();
882 kn->kn_status |= KN_DISABLED;
883 splx(s);
884 }
885
886 /* enable knote */
887 if ((kev->flags & EV_ENABLE) && (kn->kn_status & KN_DISABLED)) {
888 s = splsched();
889 kn->kn_status &= ~KN_DISABLED;
890 if ((kn->kn_status & KN_ACTIVE) &&
891 ((kn->kn_status & KN_QUEUED) == 0))
892 knote_enqueue(kn);
893 splx(s);
894 }
895
896 done:
897 if (fp != NULL)
898 FILE_UNUSE(fp, l);
899 return (error);
900 }
901
902 /*
903 * Scan through the list of events on fp (for a maximum of maxevents),
904 * returning the results in to ulistp. Timeout is determined by tsp; if
905 * NULL, wait indefinitely, if 0 valued, perform a poll, otherwise wait
906 * as appropriate.
907 */
908 static int
909 kqueue_scan(struct file *fp, size_t maxevents, struct kevent *ulistp,
910 const struct timespec *tsp, struct lwp *l, register_t *retval,
911 const struct kevent_ops *keops)
912 {
913 struct proc *p = l->l_proc;
914 struct kqueue *kq;
915 struct kevent *kevp;
916 struct timeval atv, sleeptv;
917 struct knote *kn, *marker=NULL;
918 size_t count, nkev, nevents;
919 int s, timeout, error;
920
921 kq = (struct kqueue *)fp->f_data;
922 count = maxevents;
923 nkev = nevents = error = 0;
924 if (count == 0)
925 goto done;
926
927 if (tsp) { /* timeout supplied */
928 TIMESPEC_TO_TIMEVAL(&atv, tsp);
929 if (inittimeleft(&atv, &sleeptv) == -1) {
930 error = EINVAL;
931 goto done;
932 }
933 timeout = tvtohz(&atv);
934 if (timeout <= 0)
935 timeout = -1; /* do poll */
936 } else {
937 /* no timeout, wait forever */
938 timeout = 0;
939 }
940
941 MALLOC(marker, struct knote *, sizeof(*marker), M_KEVENT, M_WAITOK);
942 memset(marker, 0, sizeof(*marker));
943
944 goto start;
945
946 retry:
947 if (tsp && (timeout = gettimeleft(&atv, &sleeptv)) <= 0) {
948 goto done;
949 }
950
951 start:
952 kevp = kq->kq_kev;
953 s = splsched();
954 simple_lock(&kq->kq_lock);
955 if (kq->kq_count == 0) {
956 if (timeout < 0) {
957 error = EWOULDBLOCK;
958 simple_unlock(&kq->kq_lock);
959 } else {
960 kq->kq_state |= KQ_SLEEP;
961 error = ltsleep(kq, PSOCK | PCATCH | PNORELOCK,
962 "kqread", timeout, &kq->kq_lock);
963 }
964 splx(s);
965 if (error == 0)
966 goto retry;
967 /* don't restart after signals... */
968 if (error == ERESTART)
969 error = EINTR;
970 else if (error == EWOULDBLOCK)
971 error = 0;
972 goto done;
973 }
974
975 /* mark end of knote list */
976 TAILQ_INSERT_TAIL(&kq->kq_head, marker, kn_tqe);
977 simple_unlock(&kq->kq_lock);
978
979 while (count) { /* while user wants data ... */
980 simple_lock(&kq->kq_lock);
981 kn = TAILQ_FIRST(&kq->kq_head); /* get next knote */
982 TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe);
983 if (kn == marker) { /* if it's our marker, stop */
984 /* What if it's some else's marker? */
985 simple_unlock(&kq->kq_lock);
986 splx(s);
987 if (count == maxevents)
988 goto retry;
989 goto done;
990 }
991 kq->kq_count--;
992 simple_unlock(&kq->kq_lock);
993
994 if (kn->kn_status & KN_DISABLED) {
995 /* don't want disabled events */
996 kn->kn_status &= ~KN_QUEUED;
997 continue;
998 }
999 if ((kn->kn_flags & EV_ONESHOT) == 0 &&
1000 kn->kn_fop->f_event(kn, 0) == 0) {
1001 /*
1002 * non-ONESHOT event that hasn't
1003 * triggered again, so de-queue.
1004 */
1005 kn->kn_status &= ~(KN_QUEUED | KN_ACTIVE);
1006 continue;
1007 }
1008 *kevp = kn->kn_kevent;
1009 kevp++;
1010 nkev++;
1011 if (kn->kn_flags & EV_ONESHOT) {
1012 /* delete ONESHOT events after retrieval */
1013 kn->kn_status &= ~KN_QUEUED;
1014 splx(s);
1015 kn->kn_fop->f_detach(kn);
1016 knote_drop(kn, l, p->p_fd);
1017 s = splsched();
1018 } else if (kn->kn_flags & EV_CLEAR) {
1019 /* clear state after retrieval */
1020 kn->kn_data = 0;
1021 kn->kn_fflags = 0;
1022 kn->kn_status &= ~(KN_QUEUED | KN_ACTIVE);
1023 } else {
1024 /* add event back on list */
1025 simple_lock(&kq->kq_lock);
1026 TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe);
1027 kq->kq_count++;
1028 simple_unlock(&kq->kq_lock);
1029 }
1030 count--;
1031 if (nkev == KQ_NEVENTS) {
1032 /* do copyouts in KQ_NEVENTS chunks */
1033 splx(s);
1034 error = (*keops->keo_put_events)(keops->keo_private,
1035 &kq->kq_kev[0], ulistp, nevents, nkev);
1036 nevents += nkev;
1037 nkev = 0;
1038 kevp = kq->kq_kev;
1039 s = splsched();
1040 if (error)
1041 break;
1042 }
1043 }
1044
1045 /* remove marker */
1046 simple_lock(&kq->kq_lock);
1047 TAILQ_REMOVE(&kq->kq_head, marker, kn_tqe);
1048 simple_unlock(&kq->kq_lock);
1049 splx(s);
1050 done:
1051 if (marker)
1052 FREE(marker, M_KEVENT);
1053
1054 if (nkev != 0)
1055 /* copyout remaining events */
1056 error = (*keops->keo_put_events)(keops->keo_private,
1057 &kq->kq_kev[0], ulistp, nevents, nkev);
1058 *retval = maxevents - count;
1059
1060 return (error);
1061 }
1062
1063 /*
1064 * struct fileops read method for a kqueue descriptor.
1065 * Not implemented.
1066 * XXX: This could be expanded to call kqueue_scan, if desired.
1067 */
1068 /*ARGSUSED*/
1069 static int
1070 kqueue_read(struct file *fp, off_t *offset, struct uio *uio, kauth_cred_t cred,
1071 int flags)
1072 {
1073
1074 return (ENXIO);
1075 }
1076
1077 /*
1078 * struct fileops write method for a kqueue descriptor.
1079 * Not implemented.
1080 */
1081 /*ARGSUSED*/
1082 static int
1083 kqueue_write(struct file *fp, off_t *offset, struct uio *uio, kauth_cred_t cred,
1084 int flags)
1085 {
1086
1087 return (ENXIO);
1088 }
1089
1090 /*
1091 * struct fileops ioctl method for a kqueue descriptor.
1092 *
1093 * Two ioctls are currently supported. They both use struct kfilter_mapping:
1094 * KFILTER_BYNAME find name for filter, and return result in
1095 * name, which is of size len.
1096 * KFILTER_BYFILTER find filter for name. len is ignored.
1097 */
1098 /*ARGSUSED*/
1099 static int
1100 kqueue_ioctl(struct file *fp, u_long com, void *data, struct lwp *l)
1101 {
1102 struct kfilter_mapping *km;
1103 const struct kfilter *kfilter;
1104 char *name;
1105 int error;
1106
1107 km = (struct kfilter_mapping *)data;
1108 error = 0;
1109
1110 switch (com) {
1111 case KFILTER_BYFILTER: /* convert filter -> name */
1112 kfilter = kfilter_byfilter(km->filter);
1113 if (kfilter != NULL)
1114 error = copyoutstr(kfilter->name, km->name, km->len,
1115 NULL);
1116 else
1117 error = ENOENT;
1118 break;
1119
1120 case KFILTER_BYNAME: /* convert name -> filter */
1121 MALLOC(name, char *, KFILTER_MAXNAME, M_KEVENT, M_WAITOK);
1122 error = copyinstr(km->name, name, KFILTER_MAXNAME, NULL);
1123 if (error) {
1124 FREE(name, M_KEVENT);
1125 break;
1126 }
1127 kfilter = kfilter_byname(name);
1128 if (kfilter != NULL)
1129 km->filter = kfilter->filter;
1130 else
1131 error = ENOENT;
1132 FREE(name, M_KEVENT);
1133 break;
1134
1135 default:
1136 error = ENOTTY;
1137
1138 }
1139 return (error);
1140 }
1141
1142 /*
1143 * struct fileops fcntl method for a kqueue descriptor.
1144 * Not implemented.
1145 */
1146 /*ARGSUSED*/
1147 static int
1148 kqueue_fcntl(struct file *fp, u_int com, void *data, struct lwp *l)
1149 {
1150
1151 return (ENOTTY);
1152 }
1153
1154 /*
1155 * struct fileops poll method for a kqueue descriptor.
1156 * Determine if kqueue has events pending.
1157 */
1158 static int
1159 kqueue_poll(struct file *fp, int events, struct lwp *l)
1160 {
1161 struct kqueue *kq;
1162 int revents;
1163
1164 kq = (struct kqueue *)fp->f_data;
1165 revents = 0;
1166 if (events & (POLLIN | POLLRDNORM)) {
1167 if (kq->kq_count) {
1168 revents |= events & (POLLIN | POLLRDNORM);
1169 } else {
1170 selrecord(l, &kq->kq_sel);
1171 }
1172 }
1173 return (revents);
1174 }
1175
1176 /*
1177 * struct fileops stat method for a kqueue descriptor.
1178 * Returns dummy info, with st_size being number of events pending.
1179 */
1180 static int
1181 kqueue_stat(struct file *fp, struct stat *st, struct lwp *l)
1182 {
1183 struct kqueue *kq;
1184
1185 kq = (struct kqueue *)fp->f_data;
1186 memset((void *)st, 0, sizeof(*st));
1187 st->st_size = kq->kq_count;
1188 st->st_blksize = sizeof(struct kevent);
1189 st->st_mode = S_IFIFO;
1190 return (0);
1191 }
1192
1193 /*
1194 * struct fileops close method for a kqueue descriptor.
1195 * Cleans up kqueue.
1196 */
1197 static int
1198 kqueue_close(struct file *fp, struct lwp *l)
1199 {
1200 struct proc *p = l->l_proc;
1201 struct kqueue *kq;
1202 struct filedesc *fdp;
1203 struct knote **knp, *kn, *kn0;
1204 int i;
1205
1206 kq = (struct kqueue *)fp->f_data;
1207 fdp = p->p_fd;
1208 for (i = 0; i < fdp->fd_knlistsize; i++) {
1209 knp = &SLIST_FIRST(&fdp->fd_knlist[i]);
1210 kn = *knp;
1211 while (kn != NULL) {
1212 kn0 = SLIST_NEXT(kn, kn_link);
1213 if (kq == kn->kn_kq) {
1214 kn->kn_fop->f_detach(kn);
1215 FILE_UNUSE(kn->kn_fp, l);
1216 pool_put(&knote_pool, kn);
1217 *knp = kn0;
1218 } else {
1219 knp = &SLIST_NEXT(kn, kn_link);
1220 }
1221 kn = kn0;
1222 }
1223 }
1224 if (fdp->fd_knhashmask != 0) {
1225 for (i = 0; i < fdp->fd_knhashmask + 1; i++) {
1226 knp = &SLIST_FIRST(&fdp->fd_knhash[i]);
1227 kn = *knp;
1228 while (kn != NULL) {
1229 kn0 = SLIST_NEXT(kn, kn_link);
1230 if (kq == kn->kn_kq) {
1231 kn->kn_fop->f_detach(kn);
1232 /* XXX non-fd release of kn->kn_ptr */
1233 pool_put(&knote_pool, kn);
1234 *knp = kn0;
1235 } else {
1236 knp = &SLIST_NEXT(kn, kn_link);
1237 }
1238 kn = kn0;
1239 }
1240 }
1241 }
1242 pool_put(&kqueue_pool, kq);
1243 fp->f_data = NULL;
1244
1245 return (0);
1246 }
1247
1248 /*
1249 * wakeup a kqueue
1250 */
1251 static void
1252 kqueue_wakeup(struct kqueue *kq)
1253 {
1254 int s;
1255
1256 s = splsched();
1257 simple_lock(&kq->kq_lock);
1258 if (kq->kq_state & KQ_SLEEP) { /* if currently sleeping ... */
1259 kq->kq_state &= ~KQ_SLEEP;
1260 wakeup(kq); /* ... wakeup */
1261 }
1262
1263 /* Notify select/poll and kevent. */
1264 selnotify(&kq->kq_sel, 0);
1265 simple_unlock(&kq->kq_lock);
1266 splx(s);
1267 }
1268
1269 /*
1270 * struct fileops kqfilter method for a kqueue descriptor.
1271 * Event triggered when monitored kqueue changes.
1272 */
1273 /*ARGSUSED*/
1274 static int
1275 kqueue_kqfilter(struct file *fp, struct knote *kn)
1276 {
1277 struct kqueue *kq;
1278
1279 KASSERT(fp == kn->kn_fp);
1280 kq = (struct kqueue *)kn->kn_fp->f_data;
1281 if (kn->kn_filter != EVFILT_READ)
1282 return (1);
1283 kn->kn_fop = &kqread_filtops;
1284 SLIST_INSERT_HEAD(&kq->kq_sel.sel_klist, kn, kn_selnext);
1285 return (0);
1286 }
1287
1288
1289 /*
1290 * Walk down a list of knotes, activating them if their event has triggered.
1291 */
1292 void
1293 knote(struct klist *list, long hint)
1294 {
1295 struct knote *kn;
1296
1297 SLIST_FOREACH(kn, list, kn_selnext)
1298 if (kn->kn_fop->f_event(kn, hint))
1299 KNOTE_ACTIVATE(kn);
1300 }
1301
1302 /*
1303 * Remove all knotes from a specified klist
1304 */
1305 void
1306 knote_remove(struct lwp *l, struct klist *list)
1307 {
1308 struct knote *kn;
1309
1310 while ((kn = SLIST_FIRST(list)) != NULL) {
1311 kn->kn_fop->f_detach(kn);
1312 knote_drop(kn, l, l->l_proc->p_fd);
1313 }
1314 }
1315
1316 /*
1317 * Remove all knotes referencing a specified fd
1318 */
1319 void
1320 knote_fdclose(struct lwp *l, int fd)
1321 {
1322 struct filedesc *fdp;
1323 struct klist *list;
1324
1325 fdp = l->l_proc->p_fd;
1326 list = &fdp->fd_knlist[fd];
1327 knote_remove(l, list);
1328 }
1329
1330 /*
1331 * Attach a new knote to a file descriptor
1332 */
1333 static void
1334 knote_attach(struct knote *kn, struct filedesc *fdp)
1335 {
1336 struct klist *list;
1337 int size;
1338
1339 if (! kn->kn_fop->f_isfd) {
1340 /* if knote is not on an fd, store on internal hash table */
1341 if (fdp->fd_knhashmask == 0)
1342 fdp->fd_knhash = hashinit(KN_HASHSIZE, HASH_LIST,
1343 M_KEVENT, M_WAITOK, &fdp->fd_knhashmask);
1344 list = &fdp->fd_knhash[KN_HASH(kn->kn_id, fdp->fd_knhashmask)];
1345 goto done;
1346 }
1347
1348 /*
1349 * otherwise, knote is on an fd.
1350 * knotes are stored in fd_knlist indexed by kn->kn_id.
1351 */
1352 if (fdp->fd_knlistsize <= kn->kn_id) {
1353 /* expand list, it's too small */
1354 size = fdp->fd_knlistsize;
1355 while (size <= kn->kn_id) {
1356 /* grow in KQ_EXTENT chunks */
1357 size += KQ_EXTENT;
1358 }
1359 list = malloc(size * sizeof(struct klist *), M_KEVENT,M_WAITOK);
1360 if (fdp->fd_knlist) {
1361 /* copy existing knlist */
1362 memcpy((caddr_t)list, (caddr_t)fdp->fd_knlist,
1363 fdp->fd_knlistsize * sizeof(struct klist *));
1364 }
1365 /*
1366 * Zero new memory. Stylistically, SLIST_INIT() should be
1367 * used here, but that does same thing as the memset() anyway.
1368 */
1369 memset(&list[fdp->fd_knlistsize], 0,
1370 (size - fdp->fd_knlistsize) * sizeof(struct klist *));
1371
1372 /* switch to new knlist */
1373 if (fdp->fd_knlist != NULL)
1374 free(fdp->fd_knlist, M_KEVENT);
1375 fdp->fd_knlistsize = size;
1376 fdp->fd_knlist = list;
1377 }
1378
1379 /* get list head for this fd */
1380 list = &fdp->fd_knlist[kn->kn_id];
1381 done:
1382 /* add new knote */
1383 SLIST_INSERT_HEAD(list, kn, kn_link);
1384 kn->kn_status = 0;
1385 }
1386
1387 /*
1388 * Drop knote.
1389 * Should be called at spl == 0, since we don't want to hold spl
1390 * while calling FILE_UNUSE and free.
1391 */
1392 static void
1393 knote_drop(struct knote *kn, struct lwp *l, struct filedesc *fdp)
1394 {
1395 struct klist *list;
1396
1397 if (kn->kn_fop->f_isfd)
1398 list = &fdp->fd_knlist[kn->kn_id];
1399 else
1400 list = &fdp->fd_knhash[KN_HASH(kn->kn_id, fdp->fd_knhashmask)];
1401
1402 SLIST_REMOVE(list, kn, knote, kn_link);
1403 if (kn->kn_status & KN_QUEUED)
1404 knote_dequeue(kn);
1405 if (kn->kn_fop->f_isfd)
1406 FILE_UNUSE(kn->kn_fp, l);
1407 pool_put(&knote_pool, kn);
1408 }
1409
1410
1411 /*
1412 * Queue new event for knote.
1413 */
1414 static void
1415 knote_enqueue(struct knote *kn)
1416 {
1417 struct kqueue *kq;
1418 int s;
1419
1420 kq = kn->kn_kq;
1421 KASSERT((kn->kn_status & KN_QUEUED) == 0);
1422
1423 s = splsched();
1424 simple_lock(&kq->kq_lock);
1425 TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe);
1426 kn->kn_status |= KN_QUEUED;
1427 kq->kq_count++;
1428 simple_unlock(&kq->kq_lock);
1429 splx(s);
1430 kqueue_wakeup(kq);
1431 }
1432
1433 /*
1434 * Dequeue event for knote.
1435 */
1436 static void
1437 knote_dequeue(struct knote *kn)
1438 {
1439 struct kqueue *kq;
1440 int s;
1441
1442 KASSERT(kn->kn_status & KN_QUEUED);
1443 kq = kn->kn_kq;
1444
1445 s = splsched();
1446 simple_lock(&kq->kq_lock);
1447 TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe);
1448 kn->kn_status &= ~KN_QUEUED;
1449 kq->kq_count--;
1450 simple_unlock(&kq->kq_lock);
1451 splx(s);
1452 }
1453