1 /* $OpenBSD: kern_event.c,v 1.142 2020/08/12 13:49:24 visa Exp $ */ 2 3 /*- 4 * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@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.22 2001/02/23 20:32:42 jlemon Exp $ 29 */ 30 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/atomic.h> 34 #include <sys/kernel.h> 35 #include <sys/proc.h> 36 #include <sys/pledge.h> 37 #include <sys/malloc.h> 38 #include <sys/unistd.h> 39 #include <sys/file.h> 40 #include <sys/filedesc.h> 41 #include <sys/fcntl.h> 42 #include <sys/selinfo.h> 43 #include <sys/queue.h> 44 #include <sys/event.h> 45 #include <sys/eventvar.h> 46 #include <sys/ktrace.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/poll.h> 55 #include <sys/syscallargs.h> 56 #include <sys/time.h> 57 #include <sys/timeout.h> 58 #include <sys/wait.h> 59 60 void kqueue_terminate(struct proc *p, struct kqueue *); 61 void kqueue_free(struct kqueue *); 62 void kqueue_init(void); 63 void KQREF(struct kqueue *); 64 void KQRELE(struct kqueue *); 65 66 int kqueue_sleep(struct kqueue *, struct timespec *); 67 int kqueue_scan(struct kqueue *kq, int maxevents, 68 struct kevent *ulistp, struct timespec *timeout, 69 struct kevent *kev, struct proc *p, int *retval); 70 71 int kqueue_read(struct file *, struct uio *, int); 72 int kqueue_write(struct file *, struct uio *, int); 73 int kqueue_ioctl(struct file *fp, u_long com, caddr_t data, 74 struct proc *p); 75 int kqueue_poll(struct file *fp, int events, struct proc *p); 76 int kqueue_kqfilter(struct file *fp, struct knote *kn); 77 int kqueue_stat(struct file *fp, struct stat *st, struct proc *p); 78 int kqueue_close(struct file *fp, struct proc *p); 79 void kqueue_wakeup(struct kqueue *kq); 80 81 static void kqueue_expand_hash(struct kqueue *kq); 82 static void kqueue_expand_list(struct kqueue *kq, int fd); 83 static void kqueue_task(void *); 84 85 const struct fileops kqueueops = { 86 .fo_read = kqueue_read, 87 .fo_write = kqueue_write, 88 .fo_ioctl = kqueue_ioctl, 89 .fo_poll = kqueue_poll, 90 .fo_kqfilter = kqueue_kqfilter, 91 .fo_stat = kqueue_stat, 92 .fo_close = kqueue_close 93 }; 94 95 void knote_attach(struct knote *kn); 96 void knote_drop(struct knote *kn, struct proc *p); 97 void knote_enqueue(struct knote *kn); 98 void knote_dequeue(struct knote *kn); 99 int knote_acquire(struct knote *kn); 100 void knote_release(struct knote *kn); 101 102 void filt_kqdetach(struct knote *kn); 103 int filt_kqueue(struct knote *kn, long hint); 104 int filt_procattach(struct knote *kn); 105 void filt_procdetach(struct knote *kn); 106 int filt_proc(struct knote *kn, long hint); 107 int filt_fileattach(struct knote *kn); 108 void filt_timerexpire(void *knx); 109 int filt_timerattach(struct knote *kn); 110 void filt_timerdetach(struct knote *kn); 111 int filt_timer(struct knote *kn, long hint); 112 void filt_seltruedetach(struct knote *kn); 113 114 const struct filterops kqread_filtops = { 115 .f_flags = FILTEROP_ISFD, 116 .f_attach = NULL, 117 .f_detach = filt_kqdetach, 118 .f_event = filt_kqueue, 119 }; 120 121 const struct filterops proc_filtops = { 122 .f_flags = 0, 123 .f_attach = filt_procattach, 124 .f_detach = filt_procdetach, 125 .f_event = filt_proc, 126 }; 127 128 const struct filterops file_filtops = { 129 .f_flags = FILTEROP_ISFD, 130 .f_attach = filt_fileattach, 131 .f_detach = NULL, 132 .f_event = NULL, 133 }; 134 135 const struct filterops timer_filtops = { 136 .f_flags = 0, 137 .f_attach = filt_timerattach, 138 .f_detach = filt_timerdetach, 139 .f_event = filt_timer, 140 }; 141 142 struct pool knote_pool; 143 struct pool kqueue_pool; 144 int kq_ntimeouts = 0; 145 int kq_timeoutmax = (4 * 1024); 146 147 #define KN_HASH(val, mask) (((val) ^ (val >> 8)) & (mask)) 148 149 /* 150 * Table for for all system-defined filters. 151 */ 152 const struct filterops *const sysfilt_ops[] = { 153 &file_filtops, /* EVFILT_READ */ 154 &file_filtops, /* EVFILT_WRITE */ 155 NULL, /*&aio_filtops,*/ /* EVFILT_AIO */ 156 &file_filtops, /* EVFILT_VNODE */ 157 &proc_filtops, /* EVFILT_PROC */ 158 &sig_filtops, /* EVFILT_SIGNAL */ 159 &timer_filtops, /* EVFILT_TIMER */ 160 &file_filtops, /* EVFILT_DEVICE */ 161 &file_filtops, /* EVFILT_EXCEPT */ 162 }; 163 164 void 165 KQREF(struct kqueue *kq) 166 { 167 atomic_inc_int(&kq->kq_refs); 168 } 169 170 void 171 KQRELE(struct kqueue *kq) 172 { 173 struct filedesc *fdp; 174 175 if (atomic_dec_int_nv(&kq->kq_refs) > 0) 176 return; 177 178 fdp = kq->kq_fdp; 179 if (rw_status(&fdp->fd_lock) == RW_WRITE) { 180 LIST_REMOVE(kq, kq_next); 181 } else { 182 fdplock(fdp); 183 LIST_REMOVE(kq, kq_next); 184 fdpunlock(fdp); 185 } 186 187 kqueue_free(kq); 188 } 189 190 void 191 kqueue_free(struct kqueue *kq) 192 { 193 free(kq->kq_knlist, M_KEVENT, kq->kq_knlistsize * 194 sizeof(struct knlist)); 195 hashfree(kq->kq_knhash, KN_HASHSIZE, M_KEVENT); 196 pool_put(&kqueue_pool, kq); 197 } 198 199 void 200 kqueue_init(void) 201 { 202 pool_init(&kqueue_pool, sizeof(struct kqueue), 0, IPL_MPFLOOR, 203 PR_WAITOK, "kqueuepl", NULL); 204 pool_init(&knote_pool, sizeof(struct knote), 0, IPL_MPFLOOR, 205 PR_WAITOK, "knotepl", NULL); 206 } 207 208 int 209 filt_fileattach(struct knote *kn) 210 { 211 struct file *fp = kn->kn_fp; 212 213 return fp->f_ops->fo_kqfilter(fp, kn); 214 } 215 216 int 217 kqueue_kqfilter(struct file *fp, struct knote *kn) 218 { 219 struct kqueue *kq = kn->kn_fp->f_data; 220 221 if (kn->kn_filter != EVFILT_READ) 222 return (EINVAL); 223 224 kn->kn_fop = &kqread_filtops; 225 klist_insert(&kq->kq_sel.si_note, kn); 226 return (0); 227 } 228 229 void 230 filt_kqdetach(struct knote *kn) 231 { 232 struct kqueue *kq = kn->kn_fp->f_data; 233 234 klist_remove(&kq->kq_sel.si_note, kn); 235 } 236 237 int 238 filt_kqueue(struct knote *kn, long hint) 239 { 240 struct kqueue *kq = kn->kn_fp->f_data; 241 242 kn->kn_data = kq->kq_count; 243 return (kn->kn_data > 0); 244 } 245 246 int 247 filt_procattach(struct knote *kn) 248 { 249 struct process *pr; 250 int s; 251 252 if ((curproc->p_p->ps_flags & PS_PLEDGE) && 253 (curproc->p_p->ps_pledge & PLEDGE_PROC) == 0) 254 return pledge_fail(curproc, EPERM, PLEDGE_PROC); 255 256 if (kn->kn_id > PID_MAX) 257 return ESRCH; 258 259 pr = prfind(kn->kn_id); 260 if (pr == NULL) 261 return (ESRCH); 262 263 /* exiting processes can't be specified */ 264 if (pr->ps_flags & PS_EXITING) 265 return (ESRCH); 266 267 kn->kn_ptr.p_process = pr; 268 kn->kn_flags |= EV_CLEAR; /* automatically set */ 269 270 /* 271 * internal flag indicating registration done by kernel 272 */ 273 if (kn->kn_flags & EV_FLAG1) { 274 kn->kn_data = kn->kn_sdata; /* ppid */ 275 kn->kn_fflags = NOTE_CHILD; 276 kn->kn_flags &= ~EV_FLAG1; 277 } 278 279 s = splhigh(); 280 klist_insert(&pr->ps_klist, kn); 281 splx(s); 282 283 return (0); 284 } 285 286 /* 287 * The knote may be attached to a different process, which may exit, 288 * leaving nothing for the knote to be attached to. So when the process 289 * exits, the knote is marked as DETACHED and also flagged as ONESHOT so 290 * it will be deleted when read out. However, as part of the knote deletion, 291 * this routine is called, so a check is needed to avoid actually performing 292 * a detach, because the original process does not exist any more. 293 */ 294 void 295 filt_procdetach(struct knote *kn) 296 { 297 struct process *pr = kn->kn_ptr.p_process; 298 int s; 299 300 if (kn->kn_status & KN_DETACHED) 301 return; 302 303 s = splhigh(); 304 klist_remove(&pr->ps_klist, kn); 305 splx(s); 306 } 307 308 int 309 filt_proc(struct knote *kn, long hint) 310 { 311 u_int event; 312 313 /* 314 * mask off extra data 315 */ 316 event = (u_int)hint & NOTE_PCTRLMASK; 317 318 /* 319 * if the user is interested in this event, record it. 320 */ 321 if (kn->kn_sfflags & event) 322 kn->kn_fflags |= event; 323 324 /* 325 * process is gone, so flag the event as finished and remove it 326 * from the process's klist 327 */ 328 if (event == NOTE_EXIT) { 329 struct process *pr = kn->kn_ptr.p_process; 330 int s; 331 332 s = splhigh(); 333 kn->kn_status |= KN_DETACHED; 334 kn->kn_flags |= (EV_EOF | EV_ONESHOT); 335 kn->kn_data = W_EXITCODE(pr->ps_xexit, pr->ps_xsig); 336 klist_remove(&pr->ps_klist, kn); 337 splx(s); 338 return (1); 339 } 340 341 /* 342 * process forked, and user wants to track the new process, 343 * so attach a new knote to it, and immediately report an 344 * event with the parent's pid. 345 */ 346 if ((event == NOTE_FORK) && (kn->kn_sfflags & NOTE_TRACK)) { 347 struct kevent kev; 348 int error; 349 350 /* 351 * register knote with new process. 352 */ 353 memset(&kev, 0, sizeof(kev)); 354 kev.ident = hint & NOTE_PDATAMASK; /* pid */ 355 kev.filter = kn->kn_filter; 356 kev.flags = kn->kn_flags | EV_ADD | EV_ENABLE | EV_FLAG1; 357 kev.fflags = kn->kn_sfflags; 358 kev.data = kn->kn_id; /* parent */ 359 kev.udata = kn->kn_kevent.udata; /* preserve udata */ 360 error = kqueue_register(kn->kn_kq, &kev, NULL); 361 if (error) 362 kn->kn_fflags |= NOTE_TRACKERR; 363 } 364 365 return (kn->kn_fflags != 0); 366 } 367 368 static void 369 filt_timer_timeout_add(struct knote *kn) 370 { 371 struct timeval tv; 372 struct timeout *to = kn->kn_hook; 373 int tticks; 374 375 tv.tv_sec = kn->kn_sdata / 1000; 376 tv.tv_usec = (kn->kn_sdata % 1000) * 1000; 377 tticks = tvtohz(&tv); 378 /* Remove extra tick from tvtohz() if timeout has fired before. */ 379 if (timeout_triggered(to)) 380 tticks--; 381 timeout_add(to, (tticks > 0) ? tticks : 1); 382 } 383 384 void 385 filt_timerexpire(void *knx) 386 { 387 struct knote *kn = knx; 388 389 kn->kn_data++; 390 knote_activate(kn); 391 392 if ((kn->kn_flags & EV_ONESHOT) == 0) 393 filt_timer_timeout_add(kn); 394 } 395 396 397 /* 398 * data contains amount of time to sleep, in milliseconds 399 */ 400 int 401 filt_timerattach(struct knote *kn) 402 { 403 struct timeout *to; 404 405 if (kq_ntimeouts > kq_timeoutmax) 406 return (ENOMEM); 407 kq_ntimeouts++; 408 409 kn->kn_flags |= EV_CLEAR; /* automatically set */ 410 to = malloc(sizeof(*to), M_KEVENT, M_WAITOK); 411 timeout_set(to, filt_timerexpire, kn); 412 kn->kn_hook = to; 413 filt_timer_timeout_add(kn); 414 415 return (0); 416 } 417 418 void 419 filt_timerdetach(struct knote *kn) 420 { 421 struct timeout *to; 422 423 to = (struct timeout *)kn->kn_hook; 424 timeout_del(to); 425 free(to, M_KEVENT, sizeof(*to)); 426 kq_ntimeouts--; 427 } 428 429 int 430 filt_timer(struct knote *kn, long hint) 431 { 432 return (kn->kn_data != 0); 433 } 434 435 436 /* 437 * filt_seltrue: 438 * 439 * This filter "event" routine simulates seltrue(). 440 */ 441 int 442 filt_seltrue(struct knote *kn, long hint) 443 { 444 445 /* 446 * We don't know how much data can be read/written, 447 * but we know that it *can* be. This is about as 448 * good as select/poll does as well. 449 */ 450 kn->kn_data = 0; 451 return (1); 452 } 453 454 /* 455 * This provides full kqfilter entry for device switch tables, which 456 * has same effect as filter using filt_seltrue() as filter method. 457 */ 458 void 459 filt_seltruedetach(struct knote *kn) 460 { 461 /* Nothing to do */ 462 } 463 464 const struct filterops seltrue_filtops = { 465 .f_flags = FILTEROP_ISFD, 466 .f_attach = NULL, 467 .f_detach = filt_seltruedetach, 468 .f_event = filt_seltrue, 469 }; 470 471 int 472 seltrue_kqfilter(dev_t dev, struct knote *kn) 473 { 474 switch (kn->kn_filter) { 475 case EVFILT_READ: 476 case EVFILT_WRITE: 477 kn->kn_fop = &seltrue_filtops; 478 break; 479 default: 480 return (EINVAL); 481 } 482 483 /* Nothing more to do */ 484 return (0); 485 } 486 487 static int 488 filt_dead(struct knote *kn, long hint) 489 { 490 kn->kn_flags |= (EV_EOF | EV_ONESHOT); 491 if (kn->kn_flags & __EV_POLL) 492 kn->kn_flags |= __EV_HUP; 493 kn->kn_data = 0; 494 return (1); 495 } 496 497 static void 498 filt_deaddetach(struct knote *kn) 499 { 500 /* Nothing to do */ 501 } 502 503 const struct filterops dead_filtops = { 504 .f_flags = FILTEROP_ISFD, 505 .f_attach = NULL, 506 .f_detach = filt_deaddetach, 507 .f_event = filt_dead, 508 }; 509 510 struct kqueue * 511 kqueue_alloc(struct filedesc *fdp) 512 { 513 struct kqueue *kq; 514 515 kq = pool_get(&kqueue_pool, PR_WAITOK | PR_ZERO); 516 kq->kq_refs = 1; 517 kq->kq_fdp = fdp; 518 TAILQ_INIT(&kq->kq_head); 519 task_set(&kq->kq_task, kqueue_task, kq); 520 521 return (kq); 522 } 523 524 int 525 sys_kqueue(struct proc *p, void *v, register_t *retval) 526 { 527 struct filedesc *fdp = p->p_fd; 528 struct kqueue *kq; 529 struct file *fp; 530 int fd, error; 531 532 kq = kqueue_alloc(fdp); 533 534 fdplock(fdp); 535 error = falloc(p, &fp, &fd); 536 if (error) 537 goto out; 538 fp->f_flag = FREAD | FWRITE; 539 fp->f_type = DTYPE_KQUEUE; 540 fp->f_ops = &kqueueops; 541 fp->f_data = kq; 542 *retval = fd; 543 LIST_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_next); 544 kq = NULL; 545 fdinsert(fdp, fd, 0, fp); 546 FRELE(fp, p); 547 out: 548 fdpunlock(fdp); 549 if (kq != NULL) 550 pool_put(&kqueue_pool, kq); 551 return (error); 552 } 553 554 int 555 sys_kevent(struct proc *p, void *v, register_t *retval) 556 { 557 struct filedesc* fdp = p->p_fd; 558 struct sys_kevent_args /* { 559 syscallarg(int) fd; 560 syscallarg(const struct kevent *) changelist; 561 syscallarg(int) nchanges; 562 syscallarg(struct kevent *) eventlist; 563 syscallarg(int) nevents; 564 syscallarg(const struct timespec *) timeout; 565 } */ *uap = v; 566 struct kevent *kevp; 567 struct kqueue *kq; 568 struct file *fp; 569 struct timespec ts; 570 struct timespec *tsp = NULL; 571 int i, n, nerrors, error; 572 struct kevent kev[KQ_NEVENTS]; 573 574 if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL) 575 return (EBADF); 576 577 if (fp->f_type != DTYPE_KQUEUE) { 578 error = EBADF; 579 goto done; 580 } 581 582 if (SCARG(uap, timeout) != NULL) { 583 error = copyin(SCARG(uap, timeout), &ts, sizeof(ts)); 584 if (error) 585 goto done; 586 if (ts.tv_sec < 0 || !timespecisvalid(&ts)) { 587 error = EINVAL; 588 goto done; 589 } 590 #ifdef KTRACE 591 if (KTRPOINT(p, KTR_STRUCT)) 592 ktrreltimespec(p, &ts); 593 #endif 594 tsp = &ts; 595 } 596 597 kq = fp->f_data; 598 nerrors = 0; 599 600 while (SCARG(uap, nchanges) > 0) { 601 n = SCARG(uap, nchanges) > KQ_NEVENTS ? 602 KQ_NEVENTS : SCARG(uap, nchanges); 603 error = copyin(SCARG(uap, changelist), kev, 604 n * sizeof(struct kevent)); 605 if (error) 606 goto done; 607 #ifdef KTRACE 608 if (KTRPOINT(p, KTR_STRUCT)) 609 ktrevent(p, kev, n); 610 #endif 611 for (i = 0; i < n; i++) { 612 kevp = &kev[i]; 613 kevp->flags &= ~EV_SYSFLAGS; 614 error = kqueue_register(kq, kevp, p); 615 if (error || (kevp->flags & EV_RECEIPT)) { 616 if (SCARG(uap, nevents) != 0) { 617 kevp->flags = EV_ERROR; 618 kevp->data = error; 619 copyout(kevp, SCARG(uap, eventlist), 620 sizeof(*kevp)); 621 SCARG(uap, eventlist)++; 622 SCARG(uap, nevents)--; 623 nerrors++; 624 } else { 625 goto done; 626 } 627 } 628 } 629 SCARG(uap, nchanges) -= n; 630 SCARG(uap, changelist) += n; 631 } 632 if (nerrors) { 633 *retval = nerrors; 634 error = 0; 635 goto done; 636 } 637 638 KQREF(kq); 639 FRELE(fp, p); 640 error = kqueue_scan(kq, SCARG(uap, nevents), SCARG(uap, eventlist), 641 tsp, kev, p, &n); 642 KQRELE(kq); 643 *retval = n; 644 return (error); 645 646 done: 647 FRELE(fp, p); 648 return (error); 649 } 650 651 #ifdef KQUEUE_DEBUG 652 void 653 kqueue_do_check(struct kqueue *kq, const char *func, int line) 654 { 655 struct knote *kn; 656 int count = 0, nmarker = 0; 657 658 KERNEL_ASSERT_LOCKED(); 659 splassert(IPL_HIGH); 660 661 TAILQ_FOREACH(kn, &kq->kq_head, kn_tqe) { 662 if (kn->kn_filter == EVFILT_MARKER) { 663 if ((kn->kn_status & KN_QUEUED) != 0) 664 panic("%s:%d: kq=%p kn=%p marker QUEUED", 665 func, line, kq, kn); 666 nmarker++; 667 } else { 668 if ((kn->kn_status & KN_ACTIVE) == 0) 669 panic("%s:%d: kq=%p kn=%p knote !ACTIVE", 670 func, line, kq, kn); 671 if ((kn->kn_status & KN_QUEUED) == 0) 672 panic("%s:%d: kq=%p kn=%p knote !QUEUED", 673 func, line, kq, kn); 674 if (kn->kn_kq != kq) 675 panic("%s:%d: kq=%p kn=%p kn_kq=%p != kq", 676 func, line, kq, kn, kn->kn_kq); 677 count++; 678 if (count > kq->kq_count) 679 goto bad; 680 } 681 } 682 if (count != kq->kq_count) { 683 bad: 684 panic("%s:%d: kq=%p kq_count=%d count=%d nmarker=%d", 685 func, line, kq, kq->kq_count, count, nmarker); 686 } 687 } 688 #define kqueue_check(kq) kqueue_do_check((kq), __func__, __LINE__) 689 #else 690 #define kqueue_check(kq) do {} while (0) 691 #endif 692 693 int 694 kqueue_register(struct kqueue *kq, struct kevent *kev, struct proc *p) 695 { 696 struct filedesc *fdp = kq->kq_fdp; 697 const struct filterops *fops = NULL; 698 struct file *fp = NULL; 699 struct knote *kn = NULL, *newkn = NULL; 700 struct knlist *list = NULL; 701 int s, error = 0; 702 703 if (kev->filter < 0) { 704 if (kev->filter + EVFILT_SYSCOUNT < 0) 705 return (EINVAL); 706 fops = sysfilt_ops[~kev->filter]; /* to 0-base index */ 707 } 708 709 if (fops == NULL) { 710 /* 711 * XXX 712 * filter attach routine is responsible for ensuring that 713 * the identifier can be attached to it. 714 */ 715 return (EINVAL); 716 } 717 718 if (fops->f_flags & FILTEROP_ISFD) { 719 /* validate descriptor */ 720 if (kev->ident > INT_MAX) 721 return (EBADF); 722 } 723 724 if (kev->flags & EV_ADD) 725 newkn = pool_get(&knote_pool, PR_WAITOK | PR_ZERO); 726 727 again: 728 if (fops->f_flags & FILTEROP_ISFD) { 729 if ((fp = fd_getfile(fdp, kev->ident)) == NULL) { 730 error = EBADF; 731 goto done; 732 } 733 if (kev->flags & EV_ADD) 734 kqueue_expand_list(kq, kev->ident); 735 if (kev->ident < kq->kq_knlistsize) 736 list = &kq->kq_knlist[kev->ident]; 737 } else { 738 if (kev->flags & EV_ADD) 739 kqueue_expand_hash(kq); 740 if (kq->kq_knhashmask != 0) { 741 list = &kq->kq_knhash[ 742 KN_HASH((u_long)kev->ident, kq->kq_knhashmask)]; 743 } 744 } 745 if (list != NULL) { 746 SLIST_FOREACH(kn, list, kn_link) { 747 if (kev->filter == kn->kn_filter && 748 kev->ident == kn->kn_id) { 749 s = splhigh(); 750 if (!knote_acquire(kn)) { 751 splx(s); 752 if (fp != NULL) { 753 FRELE(fp, p); 754 fp = NULL; 755 } 756 goto again; 757 } 758 splx(s); 759 break; 760 } 761 } 762 } 763 KASSERT(kn == NULL || (kn->kn_status & KN_PROCESSING) != 0); 764 765 if (kn == NULL && ((kev->flags & EV_ADD) == 0)) { 766 error = ENOENT; 767 goto done; 768 } 769 770 /* 771 * kn now contains the matching knote, or NULL if no match. 772 * If adding a new knote, sleeping is not allowed until the knote 773 * has been inserted. 774 */ 775 if (kev->flags & EV_ADD) { 776 if (kn == NULL) { 777 kn = newkn; 778 newkn = NULL; 779 kn->kn_status = KN_PROCESSING; 780 kn->kn_fp = fp; 781 kn->kn_kq = kq; 782 kn->kn_fop = fops; 783 784 /* 785 * apply reference count to knote structure, and 786 * do not release it at the end of this routine. 787 */ 788 fp = NULL; 789 790 kn->kn_sfflags = kev->fflags; 791 kn->kn_sdata = kev->data; 792 kev->fflags = 0; 793 kev->data = 0; 794 kn->kn_kevent = *kev; 795 796 knote_attach(kn); 797 if ((error = fops->f_attach(kn)) != 0) { 798 knote_drop(kn, p); 799 goto done; 800 } 801 802 /* 803 * If this is a file descriptor filter, check if 804 * fd was closed while the knote was being added. 805 * knote_fdclose() has missed kn if the function 806 * ran before kn appeared in kq_knlist. 807 */ 808 if ((fops->f_flags & FILTEROP_ISFD) && 809 fd_checkclosed(fdp, kev->ident, kn->kn_fp)) { 810 /* 811 * Drop the knote silently without error 812 * because another thread might already have 813 * seen it. This corresponds to the insert 814 * happening in full before the close. 815 */ 816 kn->kn_fop->f_detach(kn); 817 knote_drop(kn, p); 818 goto done; 819 } 820 } else { 821 /* 822 * The user may change some filter values after the 823 * initial EV_ADD, but doing so will not reset any 824 * filters which have already been triggered. 825 */ 826 kn->kn_sfflags = kev->fflags; 827 kn->kn_sdata = kev->data; 828 kn->kn_kevent.udata = kev->udata; 829 } 830 831 s = splhigh(); 832 if (kn->kn_fop->f_event(kn, 0)) 833 knote_activate(kn); 834 splx(s); 835 836 } else if (kev->flags & EV_DELETE) { 837 kn->kn_fop->f_detach(kn); 838 knote_drop(kn, p); 839 goto done; 840 } 841 842 if ((kev->flags & EV_DISABLE) && 843 ((kn->kn_status & KN_DISABLED) == 0)) { 844 s = splhigh(); 845 kn->kn_status |= KN_DISABLED; 846 splx(s); 847 } 848 849 if ((kev->flags & EV_ENABLE) && (kn->kn_status & KN_DISABLED)) { 850 s = splhigh(); 851 kn->kn_status &= ~KN_DISABLED; 852 if (kn->kn_fop->f_event(kn, 0)) 853 kn->kn_status |= KN_ACTIVE; 854 if ((kn->kn_status & KN_ACTIVE) && 855 ((kn->kn_status & KN_QUEUED) == 0)) 856 knote_enqueue(kn); 857 splx(s); 858 } 859 860 s = splhigh(); 861 knote_release(kn); 862 splx(s); 863 done: 864 if (fp != NULL) 865 FRELE(fp, p); 866 if (newkn != NULL) 867 pool_put(&knote_pool, newkn); 868 return (error); 869 } 870 871 int 872 kqueue_sleep(struct kqueue *kq, struct timespec *tsp) 873 { 874 struct timespec elapsed, start, stop; 875 uint64_t nsecs; 876 int error; 877 878 splassert(IPL_HIGH); 879 880 if (tsp != NULL) { 881 getnanouptime(&start); 882 nsecs = MIN(TIMESPEC_TO_NSEC(tsp), MAXTSLP); 883 } else 884 nsecs = INFSLP; 885 error = tsleep_nsec(kq, PSOCK | PCATCH, "kqread", nsecs); 886 if (tsp != NULL) { 887 getnanouptime(&stop); 888 timespecsub(&stop, &start, &elapsed); 889 timespecsub(tsp, &elapsed, tsp); 890 if (tsp->tv_sec < 0) 891 timespecclear(tsp); 892 } 893 894 return (error); 895 } 896 897 int 898 kqueue_scan(struct kqueue *kq, int maxevents, struct kevent *ulistp, 899 struct timespec *tsp, struct kevent *kev, struct proc *p, int *retval) 900 { 901 struct kevent *kevp; 902 struct knote mend, mstart, *kn; 903 int s, count, nkev, error = 0; 904 905 nkev = 0; 906 kevp = kev; 907 908 count = maxevents; 909 if (count == 0) 910 goto done; 911 912 memset(&mstart, 0, sizeof(mstart)); 913 memset(&mend, 0, sizeof(mend)); 914 915 retry: 916 KASSERT(count == maxevents); 917 KASSERT(nkev == 0); 918 919 if (kq->kq_state & KQ_DYING) { 920 error = EBADF; 921 goto done; 922 } 923 924 s = splhigh(); 925 if (kq->kq_count == 0) { 926 if (tsp != NULL && !timespecisset(tsp)) { 927 splx(s); 928 error = 0; 929 goto done; 930 } 931 kq->kq_state |= KQ_SLEEP; 932 error = kqueue_sleep(kq, tsp); 933 splx(s); 934 if (error == 0 || error == EWOULDBLOCK) 935 goto retry; 936 /* don't restart after signals... */ 937 if (error == ERESTART) 938 error = EINTR; 939 goto done; 940 } 941 942 mstart.kn_filter = EVFILT_MARKER; 943 mstart.kn_status = KN_PROCESSING; 944 TAILQ_INSERT_HEAD(&kq->kq_head, &mstart, kn_tqe); 945 mend.kn_filter = EVFILT_MARKER; 946 mend.kn_status = KN_PROCESSING; 947 TAILQ_INSERT_TAIL(&kq->kq_head, &mend, kn_tqe); 948 while (count) { 949 kn = TAILQ_NEXT(&mstart, kn_tqe); 950 if (kn->kn_filter == EVFILT_MARKER) { 951 if (kn == &mend) { 952 TAILQ_REMOVE(&kq->kq_head, &mend, kn_tqe); 953 TAILQ_REMOVE(&kq->kq_head, &mstart, kn_tqe); 954 splx(s); 955 if (count == maxevents) 956 goto retry; 957 goto done; 958 } 959 960 /* Move start marker past another thread's marker. */ 961 TAILQ_REMOVE(&kq->kq_head, &mstart, kn_tqe); 962 TAILQ_INSERT_AFTER(&kq->kq_head, kn, &mstart, kn_tqe); 963 continue; 964 } 965 966 if (!knote_acquire(kn)) 967 continue; 968 969 kqueue_check(kq); 970 TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe); 971 kn->kn_status &= ~KN_QUEUED; 972 kq->kq_count--; 973 kqueue_check(kq); 974 975 if (kn->kn_status & KN_DISABLED) { 976 knote_release(kn); 977 continue; 978 } 979 if ((kn->kn_flags & EV_ONESHOT) == 0 && 980 kn->kn_fop->f_event(kn, 0) == 0) { 981 if ((kn->kn_status & KN_QUEUED) == 0) 982 kn->kn_status &= ~KN_ACTIVE; 983 knote_release(kn); 984 kqueue_check(kq); 985 continue; 986 } 987 *kevp = kn->kn_kevent; 988 kevp++; 989 nkev++; 990 if (kn->kn_flags & EV_ONESHOT) { 991 splx(s); 992 kn->kn_fop->f_detach(kn); 993 knote_drop(kn, p); 994 s = splhigh(); 995 } else if (kn->kn_flags & (EV_CLEAR | EV_DISPATCH)) { 996 if (kn->kn_flags & EV_CLEAR) { 997 kn->kn_data = 0; 998 kn->kn_fflags = 0; 999 } 1000 if (kn->kn_flags & EV_DISPATCH) 1001 kn->kn_status |= KN_DISABLED; 1002 if ((kn->kn_status & KN_QUEUED) == 0) 1003 kn->kn_status &= ~KN_ACTIVE; 1004 knote_release(kn); 1005 } else { 1006 if ((kn->kn_status & KN_QUEUED) == 0) { 1007 kqueue_check(kq); 1008 kq->kq_count++; 1009 kn->kn_status |= KN_QUEUED; 1010 TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe); 1011 } 1012 knote_release(kn); 1013 } 1014 kqueue_check(kq); 1015 count--; 1016 if (nkev == KQ_NEVENTS) { 1017 splx(s); 1018 #ifdef KTRACE 1019 if (KTRPOINT(p, KTR_STRUCT)) 1020 ktrevent(p, kev, nkev); 1021 #endif 1022 error = copyout(kev, ulistp, 1023 sizeof(struct kevent) * nkev); 1024 ulistp += nkev; 1025 nkev = 0; 1026 kevp = kev; 1027 s = splhigh(); 1028 if (error) 1029 break; 1030 } 1031 } 1032 TAILQ_REMOVE(&kq->kq_head, &mend, kn_tqe); 1033 TAILQ_REMOVE(&kq->kq_head, &mstart, kn_tqe); 1034 splx(s); 1035 done: 1036 if (nkev != 0) { 1037 #ifdef KTRACE 1038 if (KTRPOINT(p, KTR_STRUCT)) 1039 ktrevent(p, kev, nkev); 1040 #endif 1041 error = copyout(kev, ulistp, 1042 sizeof(struct kevent) * nkev); 1043 } 1044 *retval = maxevents - count; 1045 return (error); 1046 } 1047 1048 /* 1049 * XXX 1050 * This could be expanded to call kqueue_scan, if desired. 1051 */ 1052 int 1053 kqueue_read(struct file *fp, struct uio *uio, int fflags) 1054 { 1055 return (ENXIO); 1056 } 1057 1058 int 1059 kqueue_write(struct file *fp, struct uio *uio, int fflags) 1060 { 1061 return (ENXIO); 1062 } 1063 1064 int 1065 kqueue_ioctl(struct file *fp, u_long com, caddr_t data, struct proc *p) 1066 { 1067 return (ENOTTY); 1068 } 1069 1070 int 1071 kqueue_poll(struct file *fp, int events, struct proc *p) 1072 { 1073 struct kqueue *kq = (struct kqueue *)fp->f_data; 1074 int revents = 0; 1075 int s = splhigh(); 1076 1077 if (events & (POLLIN | POLLRDNORM)) { 1078 if (kq->kq_count) { 1079 revents |= events & (POLLIN | POLLRDNORM); 1080 } else { 1081 selrecord(p, &kq->kq_sel); 1082 kq->kq_state |= KQ_SEL; 1083 } 1084 } 1085 splx(s); 1086 return (revents); 1087 } 1088 1089 int 1090 kqueue_stat(struct file *fp, struct stat *st, struct proc *p) 1091 { 1092 struct kqueue *kq = fp->f_data; 1093 1094 memset(st, 0, sizeof(*st)); 1095 st->st_size = kq->kq_count; 1096 st->st_blksize = sizeof(struct kevent); 1097 st->st_mode = S_IFIFO; 1098 return (0); 1099 } 1100 1101 void 1102 kqueue_terminate(struct proc *p, struct kqueue *kq) 1103 { 1104 int i; 1105 1106 KERNEL_ASSERT_LOCKED(); 1107 1108 for (i = 0; i < kq->kq_knlistsize; i++) 1109 knote_remove(p, &kq->kq_knlist[i]); 1110 if (kq->kq_knhashmask != 0) { 1111 for (i = 0; i < kq->kq_knhashmask + 1; i++) 1112 knote_remove(p, &kq->kq_knhash[i]); 1113 } 1114 kq->kq_state |= KQ_DYING; 1115 kqueue_wakeup(kq); 1116 1117 KASSERT(klist_empty(&kq->kq_sel.si_note)); 1118 task_del(systq, &kq->kq_task); 1119 1120 } 1121 1122 int 1123 kqueue_close(struct file *fp, struct proc *p) 1124 { 1125 struct kqueue *kq = fp->f_data; 1126 1127 KERNEL_LOCK(); 1128 kqueue_terminate(p, kq); 1129 fp->f_data = NULL; 1130 1131 KQRELE(kq); 1132 1133 KERNEL_UNLOCK(); 1134 1135 return (0); 1136 } 1137 1138 static void 1139 kqueue_task(void *arg) 1140 { 1141 struct kqueue *kq = arg; 1142 1143 if (kq->kq_state & KQ_SEL) { 1144 kq->kq_state &= ~KQ_SEL; 1145 selwakeup(&kq->kq_sel); 1146 } else { 1147 KNOTE(&kq->kq_sel.si_note, 0); 1148 } 1149 KQRELE(kq); 1150 } 1151 1152 void 1153 kqueue_wakeup(struct kqueue *kq) 1154 { 1155 1156 if (kq->kq_state & KQ_SLEEP) { 1157 kq->kq_state &= ~KQ_SLEEP; 1158 wakeup(kq); 1159 } 1160 if ((kq->kq_state & KQ_SEL) || !klist_empty(&kq->kq_sel.si_note)) { 1161 /* Defer activation to avoid recursion. */ 1162 KQREF(kq); 1163 if (!task_add(systq, &kq->kq_task)) 1164 KQRELE(kq); 1165 } 1166 } 1167 1168 static void 1169 kqueue_expand_hash(struct kqueue *kq) 1170 { 1171 struct knlist *hash; 1172 u_long hashmask; 1173 1174 if (kq->kq_knhashmask == 0) { 1175 hash = hashinit(KN_HASHSIZE, M_KEVENT, M_WAITOK, &hashmask); 1176 if (kq->kq_knhashmask == 0) { 1177 kq->kq_knhash = hash; 1178 kq->kq_knhashmask = hashmask; 1179 } else { 1180 /* Another thread has allocated the hash. */ 1181 hashfree(hash, KN_HASHSIZE, M_KEVENT); 1182 } 1183 } 1184 } 1185 1186 static void 1187 kqueue_expand_list(struct kqueue *kq, int fd) 1188 { 1189 struct knlist *list; 1190 int size; 1191 1192 if (kq->kq_knlistsize <= fd) { 1193 size = kq->kq_knlistsize; 1194 while (size <= fd) 1195 size += KQEXTENT; 1196 list = mallocarray(size, sizeof(*list), M_KEVENT, M_WAITOK); 1197 if (kq->kq_knlistsize <= fd) { 1198 memcpy(list, kq->kq_knlist, 1199 kq->kq_knlistsize * sizeof(*list)); 1200 memset(&list[kq->kq_knlistsize], 0, 1201 (size - kq->kq_knlistsize) * sizeof(*list)); 1202 free(kq->kq_knlist, M_KEVENT, 1203 kq->kq_knlistsize * sizeof(*list)); 1204 kq->kq_knlist = list; 1205 kq->kq_knlistsize = size; 1206 } else { 1207 /* Another thread has expanded the list. */ 1208 free(list, M_KEVENT, size * sizeof(*list)); 1209 } 1210 } 1211 } 1212 1213 /* 1214 * Acquire a knote, return non-zero on success, 0 on failure. 1215 * 1216 * If we cannot acquire the knote we sleep and return 0. The knote 1217 * may be stale on return in this case and the caller must restart 1218 * whatever loop they are in. 1219 */ 1220 int 1221 knote_acquire(struct knote *kn) 1222 { 1223 splassert(IPL_HIGH); 1224 KASSERT(kn->kn_filter != EVFILT_MARKER); 1225 1226 if (kn->kn_status & KN_PROCESSING) { 1227 kn->kn_status |= KN_WAITING; 1228 tsleep_nsec(kn, 0, "kqepts", SEC_TO_NSEC(1)); 1229 /* knote may be stale now */ 1230 return (0); 1231 } 1232 kn->kn_status |= KN_PROCESSING; 1233 return (1); 1234 } 1235 1236 /* 1237 * Release an acquired knote, clearing KN_PROCESSING. 1238 */ 1239 void 1240 knote_release(struct knote *kn) 1241 { 1242 splassert(IPL_HIGH); 1243 KASSERT(kn->kn_filter != EVFILT_MARKER); 1244 KASSERT(kn->kn_status & KN_PROCESSING); 1245 1246 if (kn->kn_status & KN_WAITING) { 1247 kn->kn_status &= ~KN_WAITING; 1248 wakeup(kn); 1249 } 1250 kn->kn_status &= ~KN_PROCESSING; 1251 /* kn should not be accessed anymore */ 1252 } 1253 1254 /* 1255 * activate one knote. 1256 */ 1257 void 1258 knote_activate(struct knote *kn) 1259 { 1260 int s; 1261 1262 s = splhigh(); 1263 kn->kn_status |= KN_ACTIVE; 1264 if ((kn->kn_status & (KN_QUEUED | KN_DISABLED)) == 0) 1265 knote_enqueue(kn); 1266 splx(s); 1267 } 1268 1269 /* 1270 * walk down a list of knotes, activating them if their event has triggered. 1271 */ 1272 void 1273 knote(struct klist *list, long hint) 1274 { 1275 struct knote *kn, *kn0; 1276 1277 SLIST_FOREACH_SAFE(kn, &list->kl_list, kn_selnext, kn0) 1278 if (kn->kn_fop->f_event(kn, hint)) 1279 knote_activate(kn); 1280 } 1281 1282 /* 1283 * remove all knotes from a specified knlist 1284 */ 1285 void 1286 knote_remove(struct proc *p, struct knlist *list) 1287 { 1288 struct knote *kn; 1289 int s; 1290 1291 while ((kn = SLIST_FIRST(list)) != NULL) { 1292 s = splhigh(); 1293 if (!knote_acquire(kn)) { 1294 splx(s); 1295 continue; 1296 } 1297 splx(s); 1298 kn->kn_fop->f_detach(kn); 1299 knote_drop(kn, p); 1300 } 1301 } 1302 1303 /* 1304 * remove all knotes referencing a specified fd 1305 */ 1306 void 1307 knote_fdclose(struct proc *p, int fd) 1308 { 1309 struct filedesc *fdp = p->p_p->ps_fd; 1310 struct kqueue *kq; 1311 struct knlist *list; 1312 1313 /* 1314 * fdplock can be ignored if the file descriptor table is being freed 1315 * because no other thread can access the fdp. 1316 */ 1317 if (fdp->fd_refcnt != 0) 1318 fdpassertlocked(fdp); 1319 1320 if (LIST_EMPTY(&fdp->fd_kqlist)) 1321 return; 1322 1323 KERNEL_LOCK(); 1324 LIST_FOREACH(kq, &fdp->fd_kqlist, kq_next) { 1325 if (fd >= kq->kq_knlistsize) 1326 continue; 1327 1328 list = &kq->kq_knlist[fd]; 1329 knote_remove(p, list); 1330 } 1331 KERNEL_UNLOCK(); 1332 } 1333 1334 /* 1335 * handle a process exiting, including the triggering of NOTE_EXIT notes 1336 * XXX this could be more efficient, doing a single pass down the klist 1337 */ 1338 void 1339 knote_processexit(struct proc *p) 1340 { 1341 struct process *pr = p->p_p; 1342 1343 KASSERT(p == curproc); 1344 1345 KNOTE(&pr->ps_klist, NOTE_EXIT); 1346 1347 /* remove other knotes hanging off the process */ 1348 klist_invalidate(&pr->ps_klist); 1349 } 1350 1351 void 1352 knote_attach(struct knote *kn) 1353 { 1354 struct kqueue *kq = kn->kn_kq; 1355 struct knlist *list; 1356 1357 if (kn->kn_fop->f_flags & FILTEROP_ISFD) { 1358 KASSERT(kq->kq_knlistsize > kn->kn_id); 1359 list = &kq->kq_knlist[kn->kn_id]; 1360 } else { 1361 KASSERT(kq->kq_knhashmask != 0); 1362 list = &kq->kq_knhash[KN_HASH(kn->kn_id, kq->kq_knhashmask)]; 1363 } 1364 SLIST_INSERT_HEAD(list, kn, kn_link); 1365 } 1366 1367 /* 1368 * should be called at spl == 0, since we don't want to hold spl 1369 * while calling FRELE and pool_put. 1370 */ 1371 void 1372 knote_drop(struct knote *kn, struct proc *p) 1373 { 1374 struct kqueue *kq = kn->kn_kq; 1375 struct knlist *list; 1376 int s; 1377 1378 KASSERT(kn->kn_filter != EVFILT_MARKER); 1379 1380 if (kn->kn_fop->f_flags & FILTEROP_ISFD) 1381 list = &kq->kq_knlist[kn->kn_id]; 1382 else 1383 list = &kq->kq_knhash[KN_HASH(kn->kn_id, kq->kq_knhashmask)]; 1384 1385 SLIST_REMOVE(list, kn, knote, kn_link); 1386 s = splhigh(); 1387 if (kn->kn_status & KN_QUEUED) 1388 knote_dequeue(kn); 1389 if (kn->kn_status & KN_WAITING) { 1390 kn->kn_status &= ~KN_WAITING; 1391 wakeup(kn); 1392 } 1393 splx(s); 1394 if (kn->kn_fop->f_flags & FILTEROP_ISFD) 1395 FRELE(kn->kn_fp, p); 1396 pool_put(&knote_pool, kn); 1397 } 1398 1399 1400 void 1401 knote_enqueue(struct knote *kn) 1402 { 1403 struct kqueue *kq = kn->kn_kq; 1404 1405 splassert(IPL_HIGH); 1406 KASSERT(kn->kn_filter != EVFILT_MARKER); 1407 KASSERT((kn->kn_status & KN_QUEUED) == 0); 1408 1409 kqueue_check(kq); 1410 TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe); 1411 kn->kn_status |= KN_QUEUED; 1412 kq->kq_count++; 1413 kqueue_check(kq); 1414 kqueue_wakeup(kq); 1415 } 1416 1417 void 1418 knote_dequeue(struct knote *kn) 1419 { 1420 struct kqueue *kq = kn->kn_kq; 1421 1422 splassert(IPL_HIGH); 1423 KASSERT(kn->kn_filter != EVFILT_MARKER); 1424 KASSERT(kn->kn_status & KN_QUEUED); 1425 1426 kqueue_check(kq); 1427 TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe); 1428 kn->kn_status &= ~KN_QUEUED; 1429 kq->kq_count--; 1430 kqueue_check(kq); 1431 } 1432 1433 void 1434 klist_insert(struct klist *klist, struct knote *kn) 1435 { 1436 SLIST_INSERT_HEAD(&klist->kl_list, kn, kn_selnext); 1437 } 1438 1439 void 1440 klist_remove(struct klist *klist, struct knote *kn) 1441 { 1442 SLIST_REMOVE(&klist->kl_list, kn, knote, kn_selnext); 1443 } 1444 1445 int 1446 klist_empty(struct klist *klist) 1447 { 1448 return (SLIST_EMPTY(&klist->kl_list)); 1449 } 1450 1451 void 1452 klist_invalidate(struct klist *list) 1453 { 1454 struct knote *kn; 1455 struct proc *p = curproc; 1456 int s; 1457 1458 /* 1459 * NET_LOCK() must not be held because it can block another thread 1460 * in f_event with a knote acquired. 1461 */ 1462 NET_ASSERT_UNLOCKED(); 1463 1464 s = splhigh(); 1465 while ((kn = SLIST_FIRST(&list->kl_list)) != NULL) { 1466 if (!knote_acquire(kn)) 1467 continue; 1468 splx(s); 1469 kn->kn_fop->f_detach(kn); 1470 if (kn->kn_fop->f_flags & FILTEROP_ISFD) { 1471 kn->kn_fop = &dead_filtops; 1472 knote_activate(kn); 1473 s = splhigh(); 1474 knote_release(kn); 1475 } else { 1476 knote_drop(kn, p); 1477 s = splhigh(); 1478 } 1479 } 1480 splx(s); 1481 } 1482