kern_event.c (88633) | kern_event.c (89306) |
---|---|
1/*- 2 * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * | 1/*- 2 * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $FreeBSD: head/sys/kern/kern_event.c 88633 2001-12-29 07:13:47Z alfred $ | 26 * $FreeBSD: head/sys/kern/kern_event.c 89306 2002-01-13 11:58:06Z alfred $ |
27 */ 28 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/kernel.h> 32#include <sys/lock.h> 33#include <sys/mutex.h> 34#include <sys/proc.h> --- 332 unchanged lines hidden (view full) --- 367 struct file *fp; 368 int fd, error; 369 370 mtx_lock(&Giant); 371 fdp = td->td_proc->p_fd; 372 error = falloc(td, &fp, &fd); 373 if (error) 374 goto done2; | 27 */ 28 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/kernel.h> 32#include <sys/lock.h> 33#include <sys/mutex.h> 34#include <sys/proc.h> --- 332 unchanged lines hidden (view full) --- 367 struct file *fp; 368 int fd, error; 369 370 mtx_lock(&Giant); 371 fdp = td->td_proc->p_fd; 372 error = falloc(td, &fp, &fd); 373 if (error) 374 goto done2; |
375 kq = malloc(sizeof(struct kqueue), M_KQUEUE, M_WAITOK | M_ZERO); 376 TAILQ_INIT(&kq->kq_head); 377 FILE_LOCK(fp); |
|
375 fp->f_flag = FREAD | FWRITE; 376 fp->f_type = DTYPE_KQUEUE; 377 fp->f_ops = &kqueueops; | 378 fp->f_flag = FREAD | FWRITE; 379 fp->f_type = DTYPE_KQUEUE; 380 fp->f_ops = &kqueueops; |
378 kq = malloc(sizeof(struct kqueue), M_KQUEUE, M_WAITOK | M_ZERO); | |
379 TAILQ_INIT(&kq->kq_head); 380 fp->f_data = (caddr_t)kq; | 381 TAILQ_INIT(&kq->kq_head); 382 fp->f_data = (caddr_t)kq; |
383 FILE_UNLOCK(fp); 384 FILEDESC_LOCK(fdp); |
|
381 td->td_retval[0] = fd; 382 if (fdp->fd_knlistsize < 0) 383 fdp->fd_knlistsize = 0; /* this process has a kq */ | 385 td->td_retval[0] = fd; 386 if (fdp->fd_knlistsize < 0) 387 fdp->fd_knlistsize = 0; /* this process has a kq */ |
388 FILEDESC_UNLOCK(fdp); |
|
384 kq->kq_fdp = fdp; 385done2: 386 mtx_unlock(&Giant); 387 return (error); 388} 389 390#ifndef _SYS_SYSPROTO_H_ 391struct kevent_args { --- 12 unchanged lines hidden (view full) --- 404kevent(struct thread *td, struct kevent_args *uap) 405{ 406 struct kevent *kevp; 407 struct kqueue *kq; 408 struct file *fp; 409 struct timespec ts; 410 int i, n, nerrors, error; 411 | 389 kq->kq_fdp = fdp; 390done2: 391 mtx_unlock(&Giant); 392 return (error); 393} 394 395#ifndef _SYS_SYSPROTO_H_ 396struct kevent_args { --- 12 unchanged lines hidden (view full) --- 409kevent(struct thread *td, struct kevent_args *uap) 410{ 411 struct kevent *kevp; 412 struct kqueue *kq; 413 struct file *fp; 414 struct timespec ts; 415 int i, n, nerrors, error; 416 |
412 mtx_lock(&Giant); 413 if ((error = fget(td, uap->fd, &fp)) != 0) 414 goto done; 415 if (fp->f_type != DTYPE_KQUEUE) { 416 error = EBADF; 417 goto done; | 417 fp = ffind_hold(td, uap->fd); 418 if (fp == NULL || fp->f_type != DTYPE_KQUEUE) { 419 if (fp != NULL) 420 fdrop(fp, td); 421 return (EBADF); |
418 } 419 if (uap->timeout != NULL) { 420 error = copyin(uap->timeout, &ts, sizeof(ts)); 421 if (error) | 422 } 423 if (uap->timeout != NULL) { 424 error = copyin(uap->timeout, &ts, sizeof(ts)); 425 if (error) |
422 goto done; | 426 goto done_nogiant; |
423 uap->timeout = &ts; 424 } | 427 uap->timeout = &ts; 428 } |
429 mtx_lock(&Giant); |
|
425 426 kq = (struct kqueue *)fp->f_data; 427 nerrors = 0; 428 429 while (uap->nchanges > 0) { 430 n = uap->nchanges > KQ_NEVENTS ? KQ_NEVENTS : uap->nchanges; 431 error = copyin(uap->changelist, kq->kq_kev, 432 n * sizeof(struct kevent)); --- 24 unchanged lines hidden (view full) --- 457 if (nerrors) { 458 td->td_retval[0] = nerrors; 459 error = 0; 460 goto done; 461 } 462 463 error = kqueue_scan(fp, uap->nevents, uap->eventlist, uap->timeout, td); 464done: | 430 431 kq = (struct kqueue *)fp->f_data; 432 nerrors = 0; 433 434 while (uap->nchanges > 0) { 435 n = uap->nchanges > KQ_NEVENTS ? KQ_NEVENTS : uap->nchanges; 436 error = copyin(uap->changelist, kq->kq_kev, 437 n * sizeof(struct kevent)); --- 24 unchanged lines hidden (view full) --- 462 if (nerrors) { 463 td->td_retval[0] = nerrors; 464 error = 0; 465 goto done; 466 } 467 468 error = kqueue_scan(fp, uap->nevents, uap->eventlist, uap->timeout, td); 469done: |
470 mtx_unlock(&Giant); 471done_nogiant: |
|
465 if (fp != NULL) 466 fdrop(fp, td); | 472 if (fp != NULL) 473 fdrop(fp, td); |
467 mtx_unlock(&Giant); | |
468 return (error); 469} 470 471int 472kqueue_add_filteropts(int filt, struct filterops *filtops) 473{ 474 475 if (filt > 0) --- 40 unchanged lines hidden (view full) --- 516 * XXX 517 * filter attach routine is responsible for insuring that 518 * the identifier can be attached to it. 519 */ 520 printf("unknown filter: %d\n", kev->filter); 521 return (EINVAL); 522 } 523 | 474 return (error); 475} 476 477int 478kqueue_add_filteropts(int filt, struct filterops *filtops) 479{ 480 481 if (filt > 0) --- 40 unchanged lines hidden (view full) --- 522 * XXX 523 * filter attach routine is responsible for insuring that 524 * the identifier can be attached to it. 525 */ 526 printf("unknown filter: %d\n", kev->filter); 527 return (EINVAL); 528 } 529 |
530 FILEDESC_LOCK(fdp); |
|
524 if (fops->f_isfd) { 525 /* validate descriptor */ 526 if ((u_int)kev->ident >= fdp->fd_nfiles || | 531 if (fops->f_isfd) { 532 /* validate descriptor */ 533 if ((u_int)kev->ident >= fdp->fd_nfiles || |
527 (fp = fdp->fd_ofiles[kev->ident]) == NULL) | 534 (fp = fdp->fd_ofiles[kev->ident]) == NULL) { 535 FILEDESC_UNLOCK(fdp); |
528 return (EBADF); | 536 return (EBADF); |
537 } |
|
529 fhold(fp); 530 531 if (kev->ident < fdp->fd_knlistsize) { 532 SLIST_FOREACH(kn, &fdp->fd_knlist[kev->ident], kn_link) 533 if (kq == kn->kn_kq && 534 kev->filter == kn->kn_filter) 535 break; 536 } --- 5 unchanged lines hidden (view full) --- 542 KN_HASH((u_long)kev->ident, fdp->fd_knhashmask)]; 543 SLIST_FOREACH(kn, list, kn_link) 544 if (kev->ident == kn->kn_id && 545 kq == kn->kn_kq && 546 kev->filter == kn->kn_filter) 547 break; 548 } 549 } | 538 fhold(fp); 539 540 if (kev->ident < fdp->fd_knlistsize) { 541 SLIST_FOREACH(kn, &fdp->fd_knlist[kev->ident], kn_link) 542 if (kq == kn->kn_kq && 543 kev->filter == kn->kn_filter) 544 break; 545 } --- 5 unchanged lines hidden (view full) --- 551 KN_HASH((u_long)kev->ident, fdp->fd_knhashmask)]; 552 SLIST_FOREACH(kn, list, kn_link) 553 if (kev->ident == kn->kn_id && 554 kq == kn->kn_kq && 555 kev->filter == kn->kn_filter) 556 break; 557 } 558 } |
559 FILEDESC_UNLOCK(fdp); |
|
550 551 if (kn == NULL && ((kev->flags & EV_ADD) == 0)) { 552 error = ENOENT; 553 goto done; 554 } 555 556 /* 557 * kn now contains the matching knote, or NULL if no match --- 70 unchanged lines hidden (view full) --- 628 fdrop(fp, td); 629 return (error); 630} 631 632static int 633kqueue_scan(struct file *fp, int maxevents, struct kevent *ulistp, 634 const struct timespec *tsp, struct thread *td) 635{ | 560 561 if (kn == NULL && ((kev->flags & EV_ADD) == 0)) { 562 error = ENOENT; 563 goto done; 564 } 565 566 /* 567 * kn now contains the matching knote, or NULL if no match --- 70 unchanged lines hidden (view full) --- 638 fdrop(fp, td); 639 return (error); 640} 641 642static int 643kqueue_scan(struct file *fp, int maxevents, struct kevent *ulistp, 644 const struct timespec *tsp, struct thread *td) 645{ |
636 struct kqueue *kq = (struct kqueue *)fp->f_data; | 646 struct kqueue *kq; |
637 struct kevent *kevp; 638 struct timeval atv, rtv, ttv; 639 struct knote *kn, marker; 640 int s, count, timeout, nkev = 0, error = 0; 641 | 647 struct kevent *kevp; 648 struct timeval atv, rtv, ttv; 649 struct knote *kn, marker; 650 int s, count, timeout, nkev = 0, error = 0; 651 |
652 FILE_LOCK_ASSERT(fp, MA_NOTOWNED); 653 654 kq = (struct kqueue *)fp->f_data; |
|
642 count = maxevents; 643 if (count == 0) 644 goto done; 645 646 if (tsp != NULL) { 647 TIMESPEC_TO_TIMEVAL(&atv, tsp); 648 if (itimerfix(&atv)) { 649 error = EINVAL; --- 133 unchanged lines hidden (view full) --- 783{ 784 return (ENOTTY); 785} 786 787/*ARGSUSED*/ 788static int 789kqueue_poll(struct file *fp, int events, struct ucred *cred, struct thread *td) 790{ | 655 count = maxevents; 656 if (count == 0) 657 goto done; 658 659 if (tsp != NULL) { 660 TIMESPEC_TO_TIMEVAL(&atv, tsp); 661 if (itimerfix(&atv)) { 662 error = EINVAL; --- 133 unchanged lines hidden (view full) --- 796{ 797 return (ENOTTY); 798} 799 800/*ARGSUSED*/ 801static int 802kqueue_poll(struct file *fp, int events, struct ucred *cred, struct thread *td) 803{ |
791 struct kqueue *kq = (struct kqueue *)fp->f_data; | 804 struct kqueue *kq; |
792 int revents = 0; 793 int s = splnet(); 794 | 805 int revents = 0; 806 int s = splnet(); 807 |
808 kq = (struct kqueue *)fp->f_data; |
|
795 if (events & (POLLIN | POLLRDNORM)) { 796 if (kq->kq_count) { 797 revents |= events & (POLLIN | POLLRDNORM); 798 } else { 799 selrecord(td, &kq->kq_sel); 800 kq->kq_state |= KQ_SEL; 801 } 802 } 803 splx(s); 804 return (revents); 805} 806 807/*ARGSUSED*/ 808static int 809kqueue_stat(struct file *fp, struct stat *st, struct thread *td) 810{ | 809 if (events & (POLLIN | POLLRDNORM)) { 810 if (kq->kq_count) { 811 revents |= events & (POLLIN | POLLRDNORM); 812 } else { 813 selrecord(td, &kq->kq_sel); 814 kq->kq_state |= KQ_SEL; 815 } 816 } 817 splx(s); 818 return (revents); 819} 820 821/*ARGSUSED*/ 822static int 823kqueue_stat(struct file *fp, struct stat *st, struct thread *td) 824{ |
811 struct kqueue *kq = (struct kqueue *)fp->f_data; | 825 struct kqueue *kq; |
812 | 826 |
827 kq = (struct kqueue *)fp->f_data; |
|
813 bzero((void *)st, sizeof(*st)); 814 st->st_size = kq->kq_count; 815 st->st_blksize = sizeof(struct kevent); 816 st->st_mode = S_IFIFO; 817 return (0); 818} 819 820/*ARGSUSED*/ 821static int 822kqueue_close(struct file *fp, struct thread *td) 823{ 824 struct kqueue *kq = (struct kqueue *)fp->f_data; 825 struct filedesc *fdp = td->td_proc->p_fd; 826 struct knote **knp, *kn, *kn0; 827 int i; 828 | 828 bzero((void *)st, sizeof(*st)); 829 st->st_size = kq->kq_count; 830 st->st_blksize = sizeof(struct kevent); 831 st->st_mode = S_IFIFO; 832 return (0); 833} 834 835/*ARGSUSED*/ 836static int 837kqueue_close(struct file *fp, struct thread *td) 838{ 839 struct kqueue *kq = (struct kqueue *)fp->f_data; 840 struct filedesc *fdp = td->td_proc->p_fd; 841 struct knote **knp, *kn, *kn0; 842 int i; 843 |
844 FILEDESC_LOCK(fdp); |
|
829 for (i = 0; i < fdp->fd_knlistsize; i++) { 830 knp = &SLIST_FIRST(&fdp->fd_knlist[i]); 831 kn = *knp; 832 while (kn != NULL) { 833 kn0 = SLIST_NEXT(kn, kn_link); 834 if (kq == kn->kn_kq) { 835 kn->kn_fop->f_detach(kn); | 845 for (i = 0; i < fdp->fd_knlistsize; i++) { 846 knp = &SLIST_FIRST(&fdp->fd_knlist[i]); 847 kn = *knp; 848 while (kn != NULL) { 849 kn0 = SLIST_NEXT(kn, kn_link); 850 if (kq == kn->kn_kq) { 851 kn->kn_fop->f_detach(kn); |
836 fdrop(kn->kn_fp, td); 837 knote_free(kn); | |
838 *knp = kn0; | 852 *knp = kn0; |
853 FILE_LOCK(kn->kn_fp); 854 FILEDESC_UNLOCK(fdp); 855 fdrop_locked(kn->kn_fp, td); 856 knote_free(kn); 857 FILEDESC_LOCK(fdp); |
|
839 } else { 840 knp = &SLIST_NEXT(kn, kn_link); 841 } 842 kn = kn0; 843 } 844 } 845 if (fdp->fd_knhashmask != 0) { 846 for (i = 0; i < fdp->fd_knhashmask + 1; i++) { 847 knp = &SLIST_FIRST(&fdp->fd_knhash[i]); 848 kn = *knp; 849 while (kn != NULL) { 850 kn0 = SLIST_NEXT(kn, kn_link); 851 if (kq == kn->kn_kq) { 852 kn->kn_fop->f_detach(kn); | 858 } else { 859 knp = &SLIST_NEXT(kn, kn_link); 860 } 861 kn = kn0; 862 } 863 } 864 if (fdp->fd_knhashmask != 0) { 865 for (i = 0; i < fdp->fd_knhashmask + 1; i++) { 866 knp = &SLIST_FIRST(&fdp->fd_knhash[i]); 867 kn = *knp; 868 while (kn != NULL) { 869 kn0 = SLIST_NEXT(kn, kn_link); 870 if (kq == kn->kn_kq) { 871 kn->kn_fop->f_detach(kn); |
872 *knp = kn0; |
|
853 /* XXX non-fd release of kn->kn_ptr */ | 873 /* XXX non-fd release of kn->kn_ptr */ |
874 FILEDESC_UNLOCK(fdp); |
|
854 knote_free(kn); | 875 knote_free(kn); |
855 *knp = kn0; | 876 FILEDESC_LOCK(fdp); |
856 } else { 857 knp = &SLIST_NEXT(kn, kn_link); 858 } 859 kn = kn0; 860 } 861 } 862 } | 877 } else { 878 knp = &SLIST_NEXT(kn, kn_link); 879 } 880 kn = kn0; 881 } 882 } 883 } |
884 FILEDESC_UNLOCK(fdp); |
|
863 free(kq, M_KQUEUE); 864 fp->f_data = NULL; 865 866 return (0); 867} 868 869static void 870kqueue_wakeup(struct kqueue *kq) --- 39 unchanged lines hidden (view full) --- 910 911/* 912 * remove all knotes referencing a specified fd 913 */ 914void 915knote_fdclose(struct thread *td, int fd) 916{ 917 struct filedesc *fdp = td->td_proc->p_fd; | 885 free(kq, M_KQUEUE); 886 fp->f_data = NULL; 887 888 return (0); 889} 890 891static void 892kqueue_wakeup(struct kqueue *kq) --- 39 unchanged lines hidden (view full) --- 932 933/* 934 * remove all knotes referencing a specified fd 935 */ 936void 937knote_fdclose(struct thread *td, int fd) 938{ 939 struct filedesc *fdp = td->td_proc->p_fd; |
918 struct klist *list = &fdp->fd_knlist[fd]; | 940 struct klist *list; |
919 | 941 |
942 FILEDESC_LOCK(fdp); 943 list = &fdp->fd_knlist[fd]; 944 FILEDESC_UNLOCK(fdp); |
|
920 knote_remove(td, list); 921} 922 923static void 924knote_attach(struct knote *kn, struct filedesc *fdp) 925{ | 945 knote_remove(td, list); 946} 947 948static void 949knote_attach(struct knote *kn, struct filedesc *fdp) 950{ |
926 struct klist *list; 927 int size; | 951 struct klist *list, *oldlist; 952 int size, newsize; |
928 | 953 |
954 FILEDESC_LOCK(fdp); 955 |
|
929 if (! kn->kn_fop->f_isfd) { 930 if (fdp->fd_knhashmask == 0) 931 fdp->fd_knhash = hashinit(KN_HASHSIZE, M_KQUEUE, 932 &fdp->fd_knhashmask); 933 list = &fdp->fd_knhash[KN_HASH(kn->kn_id, fdp->fd_knhashmask)]; 934 goto done; 935 } 936 937 if (fdp->fd_knlistsize <= kn->kn_id) { | 956 if (! kn->kn_fop->f_isfd) { 957 if (fdp->fd_knhashmask == 0) 958 fdp->fd_knhash = hashinit(KN_HASHSIZE, M_KQUEUE, 959 &fdp->fd_knhashmask); 960 list = &fdp->fd_knhash[KN_HASH(kn->kn_id, fdp->fd_knhashmask)]; 961 goto done; 962 } 963 964 if (fdp->fd_knlistsize <= kn->kn_id) { |
965retry: |
|
938 size = fdp->fd_knlistsize; 939 while (size <= kn->kn_id) 940 size += KQEXTENT; | 966 size = fdp->fd_knlistsize; 967 while (size <= kn->kn_id) 968 size += KQEXTENT; |
969 FILEDESC_UNLOCK(fdp); |
|
941 MALLOC(list, struct klist *, 942 size * sizeof(struct klist *), M_KQUEUE, M_WAITOK); | 970 MALLOC(list, struct klist *, 971 size * sizeof(struct klist *), M_KQUEUE, M_WAITOK); |
972 FILEDESC_LOCK(fdp); 973 newsize = fdp->fd_knlistsize; 974 while (newsize <= kn->kn_id) 975 newsize += KQEXTENT; 976 if (newsize != size) { 977 FILEDESC_UNLOCK(fdp); 978 free(list, M_TEMP); 979 FILEDESC_LOCK(fdp); 980 goto retry; 981 } |
|
943 bcopy((caddr_t)fdp->fd_knlist, (caddr_t)list, 944 fdp->fd_knlistsize * sizeof(struct klist *)); 945 bzero((caddr_t)list + 946 fdp->fd_knlistsize * sizeof(struct klist *), 947 (size - fdp->fd_knlistsize) * sizeof(struct klist *)); 948 if (fdp->fd_knlist != NULL) | 982 bcopy((caddr_t)fdp->fd_knlist, (caddr_t)list, 983 fdp->fd_knlistsize * sizeof(struct klist *)); 984 bzero((caddr_t)list + 985 fdp->fd_knlistsize * sizeof(struct klist *), 986 (size - fdp->fd_knlistsize) * sizeof(struct klist *)); 987 if (fdp->fd_knlist != NULL) |
949 FREE(fdp->fd_knlist, M_KQUEUE); | 988 oldlist = fdp->fd_knlist; 989 else 990 oldlist = NULL; |
950 fdp->fd_knlistsize = size; 951 fdp->fd_knlist = list; | 991 fdp->fd_knlistsize = size; 992 fdp->fd_knlist = list; |
993 FILEDESC_UNLOCK(fdp); 994 if (oldlist != NULL) 995 FREE(oldlist, M_KQUEUE); 996 FILEDESC_LOCK(fdp); |
|
952 } 953 list = &fdp->fd_knlist[kn->kn_id]; 954done: | 997 } 998 list = &fdp->fd_knlist[kn->kn_id]; 999done: |
1000 FILEDESC_UNLOCK(fdp); |
|
955 SLIST_INSERT_HEAD(list, kn, kn_link); 956 kn->kn_status = 0; 957} 958 959/* 960 * should be called at spl == 0, since we don't want to hold spl 961 * while calling fdrop and free. 962 */ 963static void 964knote_drop(struct knote *kn, struct thread *td) 965{ 966 struct filedesc *fdp = td->td_proc->p_fd; 967 struct klist *list; 968 | 1001 SLIST_INSERT_HEAD(list, kn, kn_link); 1002 kn->kn_status = 0; 1003} 1004 1005/* 1006 * should be called at spl == 0, since we don't want to hold spl 1007 * while calling fdrop and free. 1008 */ 1009static void 1010knote_drop(struct knote *kn, struct thread *td) 1011{ 1012 struct filedesc *fdp = td->td_proc->p_fd; 1013 struct klist *list; 1014 |
1015 FILEDESC_LOCK(fdp); |
|
969 if (kn->kn_fop->f_isfd) 970 list = &fdp->fd_knlist[kn->kn_id]; 971 else 972 list = &fdp->fd_knhash[KN_HASH(kn->kn_id, fdp->fd_knhashmask)]; | 1016 if (kn->kn_fop->f_isfd) 1017 list = &fdp->fd_knlist[kn->kn_id]; 1018 else 1019 list = &fdp->fd_knhash[KN_HASH(kn->kn_id, fdp->fd_knhashmask)]; |
1020 if (kn->kn_fop->f_isfd) 1021 FILE_LOCK(kn->kn_fp); 1022 FILEDESC_UNLOCK(fdp); |
|
973 974 SLIST_REMOVE(list, kn, knote, kn_link); 975 if (kn->kn_status & KN_QUEUED) 976 knote_dequeue(kn); 977 if (kn->kn_fop->f_isfd) | 1023 1024 SLIST_REMOVE(list, kn, knote, kn_link); 1025 if (kn->kn_status & KN_QUEUED) 1026 knote_dequeue(kn); 1027 if (kn->kn_fop->f_isfd) |
978 fdrop(kn->kn_fp, td); | 1028 fdrop_locked(kn->kn_fp, td); |
979 knote_free(kn); 980} 981 982 983static void 984knote_enqueue(struct knote *kn) 985{ 986 struct kqueue *kq = kn->kn_kq; --- 43 unchanged lines hidden --- | 1029 knote_free(kn); 1030} 1031 1032 1033static void 1034knote_enqueue(struct knote *kn) 1035{ 1036 struct kqueue *kq = kn->kn_kq; --- 43 unchanged lines hidden --- |