Lines Matching +full:touch +full:- +full:timeout +full:- +full:ms

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
5 * Copyright 2004 John-Mark Gurney <jmg@FreeBSD.org>
119 const struct timespec *timeout,
191 /* XXX - move to kern_proc.c? */
218 /* XXX - ensure not influx ? */
221 mtx_assert(&(kn)->kn_kq->kq_lock, MA_OWNED); \
223 KQ_LOCK((kn)->kn_kq); \
224 (kn)->kn_status |= KN_ACTIVE; \
225 if (((kn)->kn_status & (KN_QUEUED | KN_DISABLED)) == 0) \
228 KQ_UNLOCK((kn)->kn_kq); \
231 mtx_lock(&(kq)->kq_lock); \
234 if (((kq)->kq_state & KQ_FLUXWAIT) == KQ_FLUXWAIT) { \
235 (kq)->kq_state &= ~KQ_FLUXWAIT; \
241 mtx_unlock(&(kq)->kq_lock); \
244 mtx_unlock(&(kq)->kq_lock); \
247 mtx_assert(&(kq)->kq_lock, MA_OWNED); \
250 mtx_assert(&(kq)->kq_lock, MA_NOTOWNED); \
258 knl = kn->kn_knlist; in kn_list_lock()
260 knl->kl_lock(knl->kl_lockarg); in kn_list_lock()
271 do_free = knl->kl_autodestroy && knlist_empty(knl); in kn_list_unlock()
272 knl->kl_unlock(knl->kl_lockarg); in kn_list_unlock()
283 return (kn->kn_influx > 0); in kn_in_flux()
290 KQ_OWNED(kn->kn_kq); in kn_enter_flux()
291 MPASS(kn->kn_influx < INT_MAX); in kn_enter_flux()
292 kn->kn_influx++; in kn_enter_flux()
299 KQ_OWNED(kn->kn_kq); in kn_leave_flux()
300 MPASS(kn->kn_influx > 0); in kn_leave_flux()
301 kn->kn_influx--; in kn_leave_flux()
302 return (kn->kn_influx == 0); in kn_leave_flux()
313 knl->kl_assert_lock((knl)->kl_lockarg, LA_LOCKED); \
316 knl->kl_assert_lock((knl)->kl_lockarg, LA_UNLOCKED); \
341 /* XXX - make SYSINIT to add these, and move into respective modules. */
346 * Table for all system-defined filters.
378 return (fo_kqfilter(kn->kn_fp, kn)); in filt_fileattach()
385 struct kqueue *kq = kn->kn_fp->f_data; in kqueue_kqfilter()
387 if (kn->kn_filter != EVFILT_READ) in kqueue_kqfilter()
390 kn->kn_status |= KN_KQUEUE; in kqueue_kqfilter()
391 kn->kn_fop = &kqread_filtops; in kqueue_kqfilter()
392 knlist_add(&kq->kq_sel.si_note, kn, 0); in kqueue_kqfilter()
400 struct kqueue *kq = kn->kn_fp->f_data; in filt_kqdetach()
402 knlist_remove(&kq->kq_sel.si_note, kn, 0); in filt_kqdetach()
409 struct kqueue *kq = kn->kn_fp->f_data; in filt_kqueue()
411 kn->kn_data = kq->kq_count; in filt_kqueue()
412 return (kn->kn_data > 0); in filt_kqueue()
415 /* XXX - move to kern_proc.c? */
424 if (kn->kn_sfflags & NOTE_EXIT) in filt_procattach()
425 p = pfind_any(kn->kn_id); in filt_procattach()
427 p = pfind(kn->kn_id); in filt_procattach()
430 if (p->p_flag & P_WEXIT) in filt_procattach()
438 kn->kn_ptr.p_proc = p; in filt_procattach()
439 kn->kn_flags |= EV_CLEAR; /* automatically set */ in filt_procattach()
445 if (kn->kn_flags & EV_FLAG2) { in filt_procattach()
446 kn->kn_flags &= ~EV_FLAG2; in filt_procattach()
447 kn->kn_data = kn->kn_sdata; /* ppid */ in filt_procattach()
448 kn->kn_fflags = NOTE_CHILD; in filt_procattach()
449 kn->kn_sfflags &= ~(NOTE_EXIT | NOTE_EXEC | NOTE_FORK); in filt_procattach()
456 if (kn->kn_flags & EV_FLAG1) { in filt_procattach()
457 kn->kn_flags &= ~EV_FLAG1; in filt_procattach()
460 knlist_add(p->p_klist, kn, 1); in filt_procattach()
484 /* XXX - move to kern_proc.c? */
489 knlist_remove(kn->kn_knlist, kn, 0); in filt_procdetach()
490 kn->kn_ptr.p_proc = NULL; in filt_procdetach()
493 /* XXX - move to kern_proc.c? */
500 p = kn->kn_ptr.p_proc; in filt_proc()
508 if (kn->kn_sfflags & event) in filt_proc()
509 kn->kn_fflags |= event; in filt_proc()
513 kn->kn_flags |= EV_EOF | EV_ONESHOT; in filt_proc()
514 kn->kn_ptr.p_proc = NULL; in filt_proc()
515 if (kn->kn_fflags & NOTE_EXIT) in filt_proc()
516 kn->kn_data = KW_EXITCODE(p->p_xexit, p->p_xsig); in filt_proc()
517 if (kn->kn_fflags == 0) in filt_proc()
518 kn->kn_flags |= EV_DROP; in filt_proc()
522 return (kn->kn_fflags != 0); in filt_proc()
543 if (SLIST_EMPTY(&list->kl_list)) in knote_fork()
547 SLIST_FOREACH(kn, &list->kl_list, kn_selnext) { in knote_fork()
548 kq = kn->kn_kq; in knote_fork()
550 if (kn_in_flux(kn) && (kn->kn_status & KN_SCAN) == 0) { in knote_fork()
558 if ((kn->kn_sfflags & NOTE_TRACK) == 0) { in knote_fork()
559 if (kn->kn_fop->f_event(kn, NOTE_FORK)) in knote_fork()
573 list->kl_unlock(list->kl_lockarg); in knote_fork()
585 kev.filter = kn->kn_filter; in knote_fork()
586 kev.flags = kn->kn_flags | EV_ADD | EV_ENABLE | EV_ONESHOT | in knote_fork()
588 kev.fflags = kn->kn_sfflags; in knote_fork()
589 kev.data = kn->kn_id; /* parent */ in knote_fork()
590 kev.udata = kn->kn_kevent.udata;/* preserve udata */ in knote_fork()
593 kn->kn_fflags |= NOTE_TRACKERR; in knote_fork()
600 kev.filter = kn->kn_filter; in knote_fork()
601 kev.flags = kn->kn_flags | EV_ADD | EV_ENABLE | EV_FLAG1; in knote_fork()
602 kev.fflags = kn->kn_sfflags; in knote_fork()
603 kev.data = kn->kn_id; /* parent */ in knote_fork()
604 kev.udata = kn->kn_kevent.udata;/* preserve udata */ in knote_fork()
607 kn->kn_fflags |= NOTE_TRACKERR; in knote_fork()
608 if (kn->kn_fop->f_event(kn, NOTE_FORK)) in knote_fork()
610 list->kl_lock(list->kl_lockarg); in knote_fork()
636 #define MS_TO_SBT(ms) (((ms) * (((uint64_t)1 << 63) / 500)) >> 32) in timer2sbintime() argument
678 return (-1); in timer2sbintime()
697 callout_reset_sbt_on(&kc->c, kc->next, 0, filt_timerexpire, kc->kn, in kqtimer_sched_callout()
698 kc->cpuid, C_ABSOLUTE); in kqtimer_sched_callout()
713 TAILQ_FOREACH_SAFE(kc, &p->p_kqtim_stop, link, kc1) { in kqtimer_proc_continue()
714 TAILQ_REMOVE(&p->p_kqtim_stop, kc, link); in kqtimer_proc_continue()
715 kc->flags &= ~KQ_TIMER_CB_ENQUEUED; in kqtimer_proc_continue()
716 if (kc->next <= now) in kqtimer_proc_continue()
717 filt_timerexpire_l(kc->kn, true); in kqtimer_proc_continue()
731 kc = kn->kn_ptr.p_v; in filt_timerexpire_l()
733 if ((kn->kn_flags & EV_ONESHOT) != 0 || kc->to == 0) { in filt_timerexpire_l()
734 kn->kn_data++; in filt_timerexpire_l()
740 if (now >= kc->next) { in filt_timerexpire_l()
741 delta = (now - kc->next) / kc->to; in filt_timerexpire_l()
744 kn->kn_data += delta; in filt_timerexpire_l()
745 kc->next += delta * kc->to; in filt_timerexpire_l()
746 if (now >= kc->next) /* overflow */ in filt_timerexpire_l()
747 kc->next = now + kc->to; in filt_timerexpire_l()
748 KNOTE_ACTIVATE(kn, 0); /* XXX - handle locking */ in filt_timerexpire_l()
752 * Initial check for stopped kc->p is racy. It is fine to in filt_timerexpire_l()
758 p = kc->p; in filt_timerexpire_l()
763 if ((kc->flags & KQ_TIMER_CB_ENQUEUED) == 0) { in filt_timerexpire_l()
764 kc->flags |= KQ_TIMER_CB_ENQUEUED; in filt_timerexpire_l()
765 TAILQ_INSERT_TAIL(&p->p_kqtim_stop, kc, link); in filt_timerexpire_l()
792 if (kn->kn_sdata < 0) in filt_timervalidate()
794 if (kn->kn_sdata == 0 && (kn->kn_flags & EV_ONESHOT) == 0) in filt_timervalidate()
795 kn->kn_sdata = 1; in filt_timervalidate()
800 if ((kn->kn_sfflags & ~(NOTE_TIMER_PRECMASK | NOTE_ABSTIME)) != 0) in filt_timervalidate()
803 *to = timer2sbintime(kn->kn_sdata, kn->kn_sfflags); in filt_timervalidate()
806 if ((kn->kn_sfflags & NOTE_ABSTIME) != 0) { in filt_timervalidate()
809 *to = MAX(0, *to - sbt); in filt_timervalidate()
821 to = -1; in filt_timerattach()
825 KASSERT(to > 0 || (kn->kn_flags & EV_ONESHOT) != 0 || in filt_timerattach()
826 (kn->kn_sfflags & NOTE_ABSTIME) != 0, in filt_timerattach()
827 ("%s: periodic timer has a calculated zero timeout", __func__)); in filt_timerattach()
829 ("%s: timer has a calculated negative timeout", __func__)); in filt_timerattach()
836 if ((kn->kn_sfflags & NOTE_ABSTIME) == 0) in filt_timerattach()
837 kn->kn_flags |= EV_CLEAR; /* automatically set */ in filt_timerattach()
838 kn->kn_status &= ~KN_DETACHED; /* knlist_add clears it */ in filt_timerattach()
839 kn->kn_ptr.p_v = kc = malloc(sizeof(*kc), M_KQUEUE, M_WAITOK); in filt_timerattach()
840 kc->kn = kn; in filt_timerattach()
841 kc->p = curproc; in filt_timerattach()
842 kc->cpuid = PCPU_GET(cpuid); in filt_timerattach()
843 kc->flags = 0; in filt_timerattach()
844 callout_init(&kc->c, 1); in filt_timerattach()
855 kc = kn->kn_ptr.p_v; in filt_timerstart()
856 if ((kn->kn_sfflags & NOTE_ABSTIME) != 0) { in filt_timerstart()
857 kc->next = to; in filt_timerstart()
858 kc->to = 0; in filt_timerstart()
860 kc->next = to + sbinuptime(); in filt_timerstart()
861 kc->to = to; in filt_timerstart()
873 kc = kn->kn_ptr.p_v; in filt_timerdetach()
875 callout_drain(&kc->c); in filt_timerdetach()
879 * Double-check, using the process mutex as an interlock. in filt_timerdetach()
881 PROC_LOCK(kc->p); in filt_timerdetach()
882 if ((kc->flags & KQ_TIMER_CB_ENQUEUED) != 0) { in filt_timerdetach()
883 kc->flags &= ~KQ_TIMER_CB_ENQUEUED; in filt_timerdetach()
884 TAILQ_REMOVE(&kc->p->p_kqtim_stop, kc, link); in filt_timerdetach()
886 pending = callout_pending(&kc->c); in filt_timerdetach()
887 PROC_UNLOCK(kc->p); in filt_timerdetach()
890 old = atomic_fetchadd_int(&kq_ncallouts, -1); in filt_timerdetach()
892 kn->kn_status |= KN_DETACHED; /* knlist_remove sets it */ in filt_timerdetach()
905 /* Handle re-added timers that update data/fflags */ in filt_timertouch()
906 if (kev->flags & EV_ADD) { in filt_timertouch()
907 kc = kn->kn_ptr.p_v; in filt_timertouch()
910 callout_drain(&kc->c); in filt_timertouch()
915 * re-adding this timer with new parameters, in filt_timertouch()
923 * - if enqueued, dequeue in filt_timertouch()
924 * - make it no longer active in filt_timertouch()
925 * - clear the count of expiration events in filt_timertouch()
927 kq = kn->kn_kq; in filt_timertouch()
929 if (kn->kn_status & KN_QUEUED) in filt_timertouch()
932 kn->kn_status &= ~KN_ACTIVE; in filt_timertouch()
933 kn->kn_data = 0; in filt_timertouch()
937 kn->kn_sfflags = kev->fflags; in filt_timertouch()
938 kn->kn_sdata = kev->data; in filt_timertouch()
941 kn->kn_flags |= EV_ERROR; in filt_timertouch()
942 kn->kn_data = error; in filt_timertouch()
949 *kev = kn->kn_kevent; in filt_timertouch()
950 if (kn->kn_flags & EV_CLEAR) { in filt_timertouch()
951 kn->kn_data = 0; in filt_timertouch()
952 kn->kn_fflags = 0; in filt_timertouch()
957 panic("filt_timertouch() - invalid type (%ld)", type); in filt_timertouch()
966 return (kn->kn_data != 0); in filt_timer()
976 kn->kn_hook = NULL; in filt_userattach()
977 if (kn->kn_fflags & NOTE_TRIGGER) in filt_userattach()
978 kn->kn_hookid = 1; in filt_userattach()
980 kn->kn_hookid = 0; in filt_userattach()
997 return (kn->kn_hookid); in filt_user()
1007 if (kev->fflags & NOTE_TRIGGER) in filt_usertouch()
1008 kn->kn_hookid = 1; in filt_usertouch()
1010 ffctrl = kev->fflags & NOTE_FFCTRLMASK; in filt_usertouch()
1011 kev->fflags &= NOTE_FFLAGSMASK; in filt_usertouch()
1017 kn->kn_sfflags &= kev->fflags; in filt_usertouch()
1021 kn->kn_sfflags |= kev->fflags; in filt_usertouch()
1025 kn->kn_sfflags = kev->fflags; in filt_usertouch()
1032 kn->kn_sdata = kev->data; in filt_usertouch()
1033 if (kev->flags & EV_CLEAR) { in filt_usertouch()
1034 kn->kn_hookid = 0; in filt_usertouch()
1035 kn->kn_data = 0; in filt_usertouch()
1036 kn->kn_fflags = 0; in filt_usertouch()
1041 *kev = kn->kn_kevent; in filt_usertouch()
1042 kev->fflags = kn->kn_sfflags; in filt_usertouch()
1043 kev->data = kn->kn_sdata; in filt_usertouch()
1044 if (kn->kn_flags & EV_CLEAR) { in filt_usertouch()
1045 kn->kn_hookid = 0; in filt_usertouch()
1046 kn->kn_data = 0; in filt_usertouch()
1047 kn->kn_fflags = 0; in filt_usertouch()
1052 panic("filt_usertouch() - invalid type (%ld)", type); in filt_usertouch()
1069 if ((uap->flags & ~(KQUEUE_CLOEXEC)) != 0) in sys_kqueuex()
1072 if ((uap->flags & KQUEUE_CLOEXEC) != 0) in sys_kqueuex()
1081 mtx_init(&kq->kq_lock, "kqueue", NULL, MTX_DEF | MTX_DUPOK); in kqueue_init()
1082 TAILQ_INIT(&kq->kq_head); in kqueue_init()
1083 knlist_init_mtx(&kq->kq_sel.si_note, &kq->kq_lock); in kqueue_init()
1084 TASK_INIT(&kq->kq_task, 0, kqueue_task, kq); in kqueue_init()
1096 fdp = td->td_proc->p_fd; in kern_kqueue()
1097 cred = td->td_ucred; in kern_kqueue()
1098 if (!chgkqcnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_KQUEUES))) in kern_kqueue()
1103 chgkqcnt(cred->cr_ruidinfo, -1, 0); in kern_kqueue()
1110 kq->kq_fdp = fdp; in kern_kqueue()
1111 kq->kq_cred = crhold(cred); in kern_kqueue()
1114 TAILQ_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_list); in kern_kqueue()
1120 td->td_retval[0] = fd; in kern_kqueue()
1130 const struct timespec *timeout; member
1143 .fd = uap->fd, in sys_kevent()
1144 .changelist = uap->changelist, in sys_kevent()
1145 .nchanges = uap->nchanges, in sys_kevent()
1146 .eventlist = uap->eventlist, in sys_kevent()
1147 .nevents = uap->nevents, in sys_kevent()
1148 .timeout = uap->timeout, in sys_kevent()
1160 struct kevent *eventlist = uap->eventlist; in kern_kevent_generic()
1164 if (uap->timeout != NULL) { in kern_kevent_generic()
1165 error = copyin(uap->timeout, &ts, sizeof(ts)); in kern_kevent_generic()
1174 ktrstructarray(struct_name, UIO_USERSPACE, uap->changelist, in kern_kevent_generic()
1175 uap->nchanges, k_ops->kevent_size); in kern_kevent_generic()
1178 error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents, in kern_kevent_generic()
1184 td->td_retval[0], k_ops->kevent_size); in kern_kevent_generic()
1191 * Copy 'count' items into the destination list pointed to by uap->eventlist.
1202 error = copyout(kevp, uap->eventlist, count * sizeof *kevp); in kevent_copyout()
1204 uap->eventlist += count; in kevent_copyout()
1209 * Copy 'count' items from the list pointed to by uap->changelist.
1220 error = copyin(uap->changelist, kevp, count * sizeof *kevp); in kevent_copyin()
1222 uap->changelist += count; in kevent_copyin()
1238 kev11.ident = kevp->ident; in kevent11_copyout()
1239 kev11.filter = kevp->filter; in kevent11_copyout()
1240 kev11.flags = kevp->flags; in kevent11_copyout()
1241 kev11.fflags = kevp->fflags; in kevent11_copyout()
1242 kev11.data = kevp->data; in kevent11_copyout()
1243 kev11.udata = kevp->udata; in kevent11_copyout()
1244 error = copyout(&kev11, uap->eventlist, sizeof(kev11)); in kevent11_copyout()
1247 uap->eventlist++; in kevent11_copyout()
1254 * Copy 'count' items from the list pointed to by uap->changelist.
1267 error = copyin(uap->changelist, &kev11, sizeof(kev11)); in kevent11_copyin()
1270 kevp->ident = kev11.ident; in kevent11_copyin()
1271 kevp->filter = kev11.filter; in kevent11_copyin()
1272 kevp->flags = kev11.flags; in kevent11_copyin()
1273 kevp->fflags = kev11.fflags; in kevent11_copyin()
1274 kevp->data = (uintptr_t)kev11.data; in kevent11_copyin()
1275 kevp->udata = kev11.udata; in kevent11_copyin()
1276 bzero(&kevp->ext, sizeof(kevp->ext)); in kevent11_copyin()
1277 uap->changelist++; in kevent11_copyin()
1293 .fd = uap->fd, in freebsd11_kevent()
1294 .changelist = uap->changelist, in freebsd11_kevent()
1295 .nchanges = uap->nchanges, in freebsd11_kevent()
1296 .eventlist = uap->eventlist, in freebsd11_kevent()
1297 .nevents = uap->nevents, in freebsd11_kevent()
1298 .timeout = uap->timeout, in freebsd11_kevent()
1307 struct kevent_copyops *k_ops, const struct timespec *timeout) in kern_kevent() argument
1322 error = kern_kevent_fp(td, fp, nchanges, nevents, k_ops, timeout); in kern_kevent()
1330 struct kevent_copyops *k_ops, const struct timespec *timeout) in kqueue_kevent() argument
1342 error = k_ops->k_copyin(k_ops->arg, keva, n); in kqueue_kevent()
1348 if (!kevp->filter) in kqueue_kevent()
1350 kevp->flags &= ~EV_SYSFLAGS; in kqueue_kevent()
1352 if (error || (kevp->flags & EV_RECEIPT)) { in kqueue_kevent()
1355 kevp->flags = EV_ERROR; in kqueue_kevent()
1356 kevp->data = error; in kqueue_kevent()
1357 (void)k_ops->k_copyout(k_ops->arg, kevp, 1); in kqueue_kevent()
1358 nevents--; in kqueue_kevent()
1362 nchanges -= n; in kqueue_kevent()
1365 td->td_retval[0] = nerrors; in kqueue_kevent()
1369 return (kqueue_scan(kq, nevents, k_ops, timeout, keva, td)); in kqueue_kevent()
1374 struct kevent_copyops *k_ops, const struct timespec *timeout) in kern_kevent_fp() argument
1382 error = kqueue_kevent(kq, td, nchanges, nevents, k_ops, timeout); in kern_kevent_fp()
1389 * used to perform one-shot polling, similar to poll() and select().
1487 sysfilt_ops[~filt].for_refcnt--; in kqueue_fo_release()
1505 if ((kev->flags & (EV_ENABLE | EV_DISABLE)) == (EV_ENABLE | EV_DISABLE)) in kqueue_register()
1515 filt = kev->filter; in kqueue_register()
1520 if (kev->flags & EV_ADD) { in kqueue_register()
1522 if (kev->flags & EV_KEEPUDATA) { in kqueue_register()
1529 * Prevent waiting with locks. Non-sleepable in kqueue_register()
1539 if (fops->f_isfd) { in kqueue_register()
1541 if (kev->ident > INT_MAX) in kqueue_register()
1544 error = fget(td, kev->ident, &cap_event_rights, &fp); in kqueue_register()
1548 if ((kev->flags & EV_ADD) == EV_ADD && kqueue_expand(kq, fops, in kqueue_register()
1549 kev->ident, M_NOWAIT) != 0) { in kqueue_register()
1553 error = kqueue_expand(kq, fops, kev->ident, mflag); in kqueue_register()
1559 if (fp->f_type == DTYPE_KQUEUE) { in kqueue_register()
1567 if (fp->f_data == kq) { in kqueue_register()
1573 * Pre-lock the filedesc before the global in kqueue_register()
1577 FILEDESC_XLOCK(td->td_proc->p_fd); in kqueue_register()
1583 if (kev->ident < kq->kq_knlistsize) { in kqueue_register()
1584 SLIST_FOREACH(kn, &kq->kq_knlist[kev->ident], kn_link) in kqueue_register()
1585 if (kev->filter == kn->kn_filter) in kqueue_register()
1589 if ((kev->flags & EV_ADD) == EV_ADD) { in kqueue_register()
1590 error = kqueue_expand(kq, fops, kev->ident, mflag); in kqueue_register()
1600 if (kev->filter == EVFILT_PROC && in kqueue_register()
1601 (kev->flags & (EV_FLAG1 | EV_FLAG2)) != 0) { in kqueue_register()
1607 } else if (kq->kq_knhashmask != 0) { in kqueue_register()
1610 list = &kq->kq_knhash[ in kqueue_register()
1611 KN_HASH((u_long)kev->ident, kq->kq_knhashmask)]; in kqueue_register()
1613 if (kev->ident == kn->kn_id && in kqueue_register()
1614 kev->filter == kn->kn_filter) in kqueue_register()
1623 FILEDESC_XUNLOCK(td->td_proc->p_fd); in kqueue_register()
1626 kq->kq_state |= KQ_FLUXWAIT; in kqueue_register()
1627 msleep(kq, &kq->kq_lock, PSOCK | PDROP, "kqflxwt", 0); in kqueue_register()
1639 if (kev->flags & EV_ADD) { in kqueue_register()
1647 kn->kn_fp = fp; in kqueue_register()
1648 kn->kn_kq = kq; in kqueue_register()
1649 kn->kn_fop = fops; in kqueue_register()
1657 kn->kn_sfflags = kev->fflags; in kqueue_register()
1658 kn->kn_sdata = kev->data; in kqueue_register()
1659 kev->fflags = 0; in kqueue_register()
1660 kev->data = 0; in kqueue_register()
1661 kn->kn_kevent = *kev; in kqueue_register()
1662 kn->kn_kevent.flags &= ~(EV_ADD | EV_DELETE | in kqueue_register()
1664 kn->kn_status = KN_DETACHED; in kqueue_register()
1665 if ((kev->flags & EV_DISABLE) != 0) in kqueue_register()
1666 kn->kn_status |= KN_DISABLED; in kqueue_register()
1676 if ((error = kn->kn_fop->f_attach(kn)) != 0) { in kqueue_register()
1690 if (kev->flags & EV_DELETE) { in kqueue_register()
1697 if (kev->flags & EV_FORCEONESHOT) { in kqueue_register()
1698 kn->kn_flags |= EV_ONESHOT; in kqueue_register()
1702 if ((kev->flags & EV_ENABLE) != 0) in kqueue_register()
1703 kn->kn_status &= ~KN_DISABLED; in kqueue_register()
1704 else if ((kev->flags & EV_DISABLE) != 0) in kqueue_register()
1705 kn->kn_status |= KN_DISABLED; in kqueue_register()
1712 kn->kn_status |= KN_SCAN; in kqueue_register()
1716 if ((kev->flags & EV_KEEPUDATA) == 0) in kqueue_register()
1717 kn->kn_kevent.udata = kev->udata; in kqueue_register()
1718 if (!fops->f_isfd && fops->f_touch != NULL) { in kqueue_register()
1719 fops->f_touch(kn, kev, EVENT_REGISTER); in kqueue_register()
1721 kn->kn_sfflags = kev->fflags; in kqueue_register()
1722 kn->kn_sdata = kev->data; in kqueue_register()
1727 * We can get here with kn->kn_knlist == NULL. This can happen when in kqueue_register()
1736 if ((kn->kn_status & KN_DISABLED) == 0) in kqueue_register()
1737 event = kn->kn_fop->f_event(kn, 0); in kqueue_register()
1743 kn->kn_status |= KN_ACTIVE; in kqueue_register()
1744 if ((kn->kn_status & (KN_ACTIVE | KN_DISABLED | KN_QUEUED)) == in kqueue_register()
1747 kn->kn_status &= ~KN_SCAN; in kqueue_register()
1755 FILEDESC_XUNLOCK(td->td_proc->p_fd); in kqueue_register()
1772 kq = fp->f_data; in kqueue_acquire()
1773 if (fp->f_type != DTYPE_KQUEUE || kq == NULL) in kqueue_acquire()
1777 if ((kq->kq_state & KQ_CLOSING) == KQ_CLOSING) { in kqueue_acquire()
1781 kq->kq_refcnt++; in kqueue_acquire()
1794 kq->kq_refcnt--; in kqueue_release()
1795 if (kq->kq_refcnt == 1) in kqueue_release()
1796 wakeup(&kq->kq_refcnt); in kqueue_release()
1811 KASSERT(((kq->kq_state & KQ_TASKDRAIN) != KQ_TASKDRAIN), in kqueue_schedtask()
1814 if ((kq->kq_state & KQ_TASKSCHED) != KQ_TASKSCHED) { in kqueue_schedtask()
1815 taskqueue_enqueue(taskqueue_kqueue_ctx, &kq->kq_task); in kqueue_schedtask()
1816 kq->kq_state |= KQ_TASKSCHED; in kqueue_schedtask()
1838 if (fops->f_isfd) { in kqueue_expand()
1840 if (kq->kq_knlistsize <= fd) { in kqueue_expand()
1841 size = kq->kq_knlistsize; in kqueue_expand()
1848 if ((kq->kq_state & KQ_CLOSING) != 0) { in kqueue_expand()
1851 } else if (kq->kq_knlistsize > fd) { in kqueue_expand()
1854 if (kq->kq_knlist != NULL) { in kqueue_expand()
1855 bcopy(kq->kq_knlist, list, in kqueue_expand()
1856 kq->kq_knlistsize * sizeof(*list)); in kqueue_expand()
1857 to_free = kq->kq_knlist; in kqueue_expand()
1858 kq->kq_knlist = NULL; in kqueue_expand()
1861 kq->kq_knlistsize * sizeof(*list), in kqueue_expand()
1862 (size - kq->kq_knlistsize) * sizeof(*list)); in kqueue_expand()
1863 kq->kq_knlistsize = size; in kqueue_expand()
1864 kq->kq_knlist = list; in kqueue_expand()
1869 if (kq->kq_knhashmask == 0) { in kqueue_expand()
1876 if ((kq->kq_state & KQ_CLOSING) != 0) { in kqueue_expand()
1879 } else if (kq->kq_knhashmask == 0) { in kqueue_expand()
1880 kq->kq_knhash = tmp_knhash; in kqueue_expand()
1881 kq->kq_knhashmask = tmp_knhashmask; in kqueue_expand()
1906 KNOTE_LOCKED(&kq->kq_sel.si_note, 0); in kqueue_task()
1908 kq->kq_state &= ~KQ_TASKSCHED; in kqueue_task()
1909 if ((kq->kq_state & KQ_TASKDRAIN) == KQ_TASKDRAIN) { in kqueue_task()
1910 wakeup(&kq->kq_state); in kqueue_task()
1928 int count, error, haskqglobal, influx, nkev, touch; in kqueue_scan() local
1949 if (tsp->tv_sec <= INT32_MAX) { in kqueue_scan()
1953 if (asbt <= SBT_MAX - rsbt) in kqueue_scan()
1961 asbt = -1; in kqueue_scan()
1965 marker->kn_status = KN_MARKER; in kqueue_scan()
1970 if (kq->kq_count == 0) { in kqueue_scan()
1971 if (asbt == -1) { in kqueue_scan()
1974 kq->kq_state |= KQ_SLEEP; in kqueue_scan()
1975 error = msleep_sbt(kq, &kq->kq_lock, PSOCK | PCATCH, in kqueue_scan()
1988 TAILQ_INSERT_TAIL(&kq->kq_head, marker, kn_tqe); in kqueue_scan()
1992 kn = TAILQ_FIRST(&kq->kq_head); in kqueue_scan()
1994 if ((kn->kn_status == KN_MARKER && kn != marker) || in kqueue_scan()
2000 kq->kq_state |= KQ_FLUXWAIT; in kqueue_scan()
2001 error = msleep(kq, &kq->kq_lock, PSOCK, in kqueue_scan()
2006 TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe); in kqueue_scan()
2007 if ((kn->kn_status & KN_DISABLED) == KN_DISABLED) { in kqueue_scan()
2008 kn->kn_status &= ~KN_QUEUED; in kqueue_scan()
2009 kq->kq_count--; in kqueue_scan()
2021 if ((kn->kn_flags & EV_DROP) == EV_DROP) { in kqueue_scan()
2022 kn->kn_status &= ~KN_QUEUED; in kqueue_scan()
2024 kq->kq_count--; in kqueue_scan()
2033 } else if ((kn->kn_flags & EV_ONESHOT) == EV_ONESHOT) { in kqueue_scan()
2034 kn->kn_status &= ~KN_QUEUED; in kqueue_scan()
2036 kq->kq_count--; in kqueue_scan()
2042 *kevp = kn->kn_kevent; in kqueue_scan()
2047 kn->kn_status |= KN_SCAN; in kqueue_scan()
2050 if ((kn->kn_status & KN_KQUEUE) == KN_KQUEUE) in kqueue_scan()
2053 if (kn->kn_fop->f_event(kn, 0) == 0) { in kqueue_scan()
2056 kn->kn_status &= ~(KN_QUEUED | KN_ACTIVE | in kqueue_scan()
2059 kq->kq_count--; in kqueue_scan()
2064 touch = (!kn->kn_fop->f_isfd && in kqueue_scan()
2065 kn->kn_fop->f_touch != NULL); in kqueue_scan()
2066 if (touch) in kqueue_scan()
2067 kn->kn_fop->f_touch(kn, kevp, EVENT_PROCESS); in kqueue_scan()
2069 *kevp = kn->kn_kevent; in kqueue_scan()
2072 if (kn->kn_flags & (EV_CLEAR | EV_DISPATCH)) { in kqueue_scan()
2075 * 'touch'ed. in kqueue_scan()
2077 if (touch == 0 && kn->kn_flags & EV_CLEAR) { in kqueue_scan()
2078 kn->kn_data = 0; in kqueue_scan()
2079 kn->kn_fflags = 0; in kqueue_scan()
2081 if (kn->kn_flags & EV_DISPATCH) in kqueue_scan()
2082 kn->kn_status |= KN_DISABLED; in kqueue_scan()
2083 kn->kn_status &= ~(KN_QUEUED | KN_ACTIVE); in kqueue_scan()
2084 kq->kq_count--; in kqueue_scan()
2086 TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe); in kqueue_scan()
2088 kn->kn_status &= ~KN_SCAN; in kqueue_scan()
2097 count--; in kqueue_scan()
2102 error = k_ops->k_copyout(k_ops->arg, keva, nkev); in kqueue_scan()
2110 TAILQ_REMOVE(&kq->kq_head, marker, kn_tqe); in kqueue_scan()
2118 error = k_ops->k_copyout(k_ops->arg, keva, nkev); in kqueue_scan()
2119 td->td_retval[0] = maxevents - count; in kqueue_scan()
2149 kq = fp->f_data; in kqueue_ioctl()
2153 kq->kq_state |= KQ_ASYNC; in kqueue_ioctl()
2155 kq->kq_state &= ~KQ_ASYNC; in kqueue_ioctl()
2160 return (fsetown(*(int *)data, &kq->kq_sigio)); in kqueue_ioctl()
2163 *(int *)data = fgetown(&kq->kq_sigio); in kqueue_ioctl()
2185 if (kq->kq_count) { in kqueue_poll()
2188 selrecord(td, &kq->kq_sel); in kqueue_poll()
2189 if (SEL_WAITING(&kq->kq_sel)) in kqueue_poll()
2190 kq->kq_state |= KQ_SEL; in kqueue_poll()
2209 * XXX - This is needed for libc_r. in kqueue_stat()
2211 st->st_mode = S_IFIFO; in kqueue_stat()
2223 KASSERT((kq->kq_state & KQ_CLOSING) != KQ_CLOSING, in kqueue_drain()
2225 kq->kq_state |= KQ_CLOSING; in kqueue_drain()
2226 if (kq->kq_refcnt > 1) in kqueue_drain()
2227 msleep(&kq->kq_refcnt, &kq->kq_lock, PSOCK, "kqclose", 0); in kqueue_drain()
2229 KASSERT(kq->kq_refcnt == 1, ("other refs are out there!")); in kqueue_drain()
2231 KASSERT(knlist_empty(&kq->kq_sel.si_note), in kqueue_drain()
2234 for (i = 0; i < kq->kq_knlistsize; i++) { in kqueue_drain()
2235 while ((kn = SLIST_FIRST(&kq->kq_knlist[i])) != NULL) { in kqueue_drain()
2237 kq->kq_state |= KQ_FLUXWAIT; in kqueue_drain()
2238 msleep(kq, &kq->kq_lock, PSOCK, "kqclo1", 0); in kqueue_drain()
2247 if (kq->kq_knhashmask != 0) { in kqueue_drain()
2248 for (i = 0; i <= kq->kq_knhashmask; i++) { in kqueue_drain()
2249 while ((kn = SLIST_FIRST(&kq->kq_knhash[i])) != NULL) { in kqueue_drain()
2251 kq->kq_state |= KQ_FLUXWAIT; in kqueue_drain()
2252 msleep(kq, &kq->kq_lock, PSOCK, in kqueue_drain()
2264 if ((kq->kq_state & KQ_TASKSCHED) == KQ_TASKSCHED) { in kqueue_drain()
2265 kq->kq_state |= KQ_TASKDRAIN; in kqueue_drain()
2266 msleep(&kq->kq_state, &kq->kq_lock, PSOCK, "kqtqdr", 0); in kqueue_drain()
2269 if ((kq->kq_state & KQ_SEL) == KQ_SEL) { in kqueue_drain()
2270 selwakeuppri(&kq->kq_sel, PSOCK); in kqueue_drain()
2271 if (!SEL_WAITING(&kq->kq_sel)) in kqueue_drain()
2272 kq->kq_state &= ~KQ_SEL; in kqueue_drain()
2282 KASSERT(kq->kq_fdp == NULL, in kqueue_destroy()
2284 seldrain(&kq->kq_sel); in kqueue_destroy()
2285 knlist_destroy(&kq->kq_sel.si_note); in kqueue_destroy()
2286 mtx_destroy(&kq->kq_lock); in kqueue_destroy()
2288 if (kq->kq_knhash != NULL) in kqueue_destroy()
2289 free(kq->kq_knhash, M_KQUEUE); in kqueue_destroy()
2290 if (kq->kq_knlist != NULL) in kqueue_destroy()
2291 free(kq->kq_knlist, M_KQUEUE); in kqueue_destroy()
2293 funsetown(&kq->kq_sigio); in kqueue_destroy()
2300 struct kqueue *kq = fp->f_data; in kqueue_close()
2313 * take the sleepable lock after non-sleepable. in kqueue_close()
2315 fdp = kq->kq_fdp; in kqueue_close()
2316 kq->kq_fdp = NULL; in kqueue_close()
2322 TAILQ_REMOVE(&fdp->fd_kqlist, kq, kq_list); in kqueue_close()
2327 chgkqcnt(kq->kq_cred->cr_ruidinfo, -1, 0); in kqueue_close()
2328 crfree(kq->kq_cred); in kqueue_close()
2330 fp->f_data = NULL; in kqueue_close()
2338 struct kqueue *kq = fp->f_data; in kqueue_fill_kinfo()
2340 kif->kf_type = KF_TYPE_KQUEUE; in kqueue_fill_kinfo()
2341 kif->kf_un.kf_kqueue.kf_kqueue_addr = (uintptr_t)kq; in kqueue_fill_kinfo()
2342 kif->kf_un.kf_kqueue.kf_kqueue_count = kq->kq_count; in kqueue_fill_kinfo()
2343 kif->kf_un.kf_kqueue.kf_kqueue_state = kq->kq_state; in kqueue_fill_kinfo()
2352 if ((kq->kq_state & KQ_SLEEP) == KQ_SLEEP) { in kqueue_wakeup()
2353 kq->kq_state &= ~KQ_SLEEP; in kqueue_wakeup()
2356 if ((kq->kq_state & KQ_SEL) == KQ_SEL) { in kqueue_wakeup()
2357 selwakeuppri(&kq->kq_sel, PSOCK); in kqueue_wakeup()
2358 if (!SEL_WAITING(&kq->kq_sel)) in kqueue_wakeup()
2359 kq->kq_state &= ~KQ_SEL; in kqueue_wakeup()
2361 if (!knlist_empty(&kq->kq_sel.si_note)) in kqueue_wakeup()
2363 if ((kq->kq_state & KQ_ASYNC) == KQ_ASYNC) { in kqueue_wakeup()
2364 pgsigio(&kq->kq_sigio, SIGIO, 0); in kqueue_wakeup()
2389 list->kl_lock(list->kl_lockarg); in knote()
2398 SLIST_FOREACH_SAFE(kn, &list->kl_list, kn_selnext, tkn) { in knote()
2399 kq = kn->kn_kq; in knote()
2401 if (kn_in_flux(kn) && (kn->kn_status & KN_SCAN) == 0) { in knote()
2414 error = kn->kn_fop->f_event(kn, hint); in knote()
2421 if (kn->kn_fop->f_event(kn, hint)) in knote()
2427 list->kl_unlock(list->kl_lockarg); in knote()
2438 KQ_NOTOWNED(kn->kn_kq); in knlist_add()
2440 KASSERT((kn->kn_status & KN_DETACHED) != 0, in knlist_add()
2443 knl->kl_lock(knl->kl_lockarg); in knlist_add()
2444 SLIST_INSERT_HEAD(&knl->kl_list, kn, kn_selnext); in knlist_add()
2446 knl->kl_unlock(knl->kl_lockarg); in knlist_add()
2447 KQ_LOCK(kn->kn_kq); in knlist_add()
2448 kn->kn_knlist = knl; in knlist_add()
2449 kn->kn_status &= ~KN_DETACHED; in knlist_add()
2450 KQ_UNLOCK(kn->kn_kq); in knlist_add()
2460 mtx_assert(&kn->kn_kq->kq_lock, kqislocked ? MA_OWNED : MA_NOTOWNED); in knlist_remove_kq()
2462 KASSERT((kn->kn_status & KN_DETACHED) == 0, in knlist_remove_kq()
2465 knl->kl_lock(knl->kl_lockarg); in knlist_remove_kq()
2466 SLIST_REMOVE(&knl->kl_list, kn, knote, kn_selnext); in knlist_remove_kq()
2467 kn->kn_knlist = NULL; in knlist_remove_kq()
2471 KQ_LOCK(kn->kn_kq); in knlist_remove_kq()
2472 kn->kn_status |= KN_DETACHED; in knlist_remove_kq()
2474 KQ_UNLOCK(kn->kn_kq); in knlist_remove_kq()
2492 return (SLIST_EMPTY(&knl->kl_list)); in knlist_empty()
2532 knl->kl_lockarg = &knlist_lock; in knlist_init()
2534 knl->kl_lockarg = lock; in knlist_init()
2537 knl->kl_lock = knlist_mtx_lock; in knlist_init()
2539 knl->kl_lock = kl_lock; in knlist_init()
2541 knl->kl_unlock = knlist_mtx_unlock; in knlist_init()
2543 knl->kl_unlock = kl_unlock; in knlist_init()
2545 knl->kl_assert_lock = knlist_mtx_assert_lock; in knlist_init()
2547 knl->kl_assert_lock = kl_assert_lock; in knlist_init()
2549 knl->kl_autodestroy = 0; in knlist_init()
2550 SLIST_INIT(&knl->kl_list); in knlist_init()
2583 knl->kl_autodestroy = 1; in knlist_detach()
2600 KASSERT(!knl->kl_autodestroy, ("cleardel for autodestroy %p", knl)); in knlist_cleardel()
2606 knl->kl_lock(knl->kl_lockarg); in knlist_cleardel()
2609 SLIST_FOREACH_SAFE(kn, &knl->kl_list, kn_selnext, kn2) { in knlist_cleardel()
2610 kq = kn->kn_kq; in knlist_cleardel()
2623 kn->kn_flags |= EV_EOF | EV_ONESHOT; in knlist_cleardel()
2629 if (!SLIST_EMPTY(&knl->kl_list)) { in knlist_cleardel()
2631 kn = SLIST_FIRST(&knl->kl_list); in knlist_cleardel()
2632 kq = kn->kn_kq; in knlist_cleardel()
2635 knl->kl_unlock(knl->kl_lockarg); in knlist_cleardel()
2636 kq->kq_state |= KQ_FLUXWAIT; in knlist_cleardel()
2637 msleep(kq, &kq->kq_lock, PSOCK | PDROP, "kqkclr", 0); in knlist_cleardel()
2645 knl->kl_unlock(knl->kl_lockarg); in knlist_cleardel()
2658 struct filedesc *fdp = td->td_proc->p_fd; in knote_fdclose()
2669 TAILQ_FOREACH(kq, &fdp->fd_kqlist, kq_list) { in knote_fdclose()
2674 while (kq->kq_knlistsize > fd && in knote_fdclose()
2675 (kn = SLIST_FIRST(&kq->kq_knlist[fd])) != NULL) { in knote_fdclose()
2680 kq->kq_state |= KQ_FLUXWAIT; in knote_fdclose()
2681 msleep(kq, &kq->kq_lock, PSOCK, "kqflxwt", 0); in knote_fdclose()
2702 if ((kq->kq_state & KQ_CLOSING) != 0) in knote_attach()
2704 if (kn->kn_fop->f_isfd) { in knote_attach()
2705 if (kn->kn_id >= kq->kq_knlistsize) in knote_attach()
2707 list = &kq->kq_knlist[kn->kn_id]; in knote_attach()
2709 if (kq->kq_knhash == NULL) in knote_attach()
2711 list = &kq->kq_knhash[KN_HASH(kn->kn_id, kq->kq_knhashmask)]; in knote_attach()
2721 if ((kn->kn_status & KN_DETACHED) == 0) in knote_drop()
2722 kn->kn_fop->f_detach(kn); in knote_drop()
2732 kq = kn->kn_kq; in knote_drop_detached()
2734 KASSERT((kn->kn_status & KN_DETACHED) != 0, in knote_drop_detached()
2740 KASSERT(kn->kn_influx >= 1, in knote_drop_detached()
2742 kn, kn->kn_influx)); in knote_drop_detached()
2743 if (kn->kn_influx == 1) in knote_drop_detached()
2745 kq->kq_state |= KQ_FLUXWAIT; in knote_drop_detached()
2746 msleep(kq, &kq->kq_lock, PSOCK, "kqflxwt", 0); in knote_drop_detached()
2749 if (kn->kn_fop->f_isfd) in knote_drop_detached()
2750 list = &kq->kq_knlist[kn->kn_id]; in knote_drop_detached()
2752 list = &kq->kq_knhash[KN_HASH(kn->kn_id, kq->kq_knhashmask)]; in knote_drop_detached()
2756 if (kn->kn_status & KN_QUEUED) in knote_drop_detached()
2760 if (kn->kn_fop->f_isfd) { in knote_drop_detached()
2761 fdrop(kn->kn_fp, td); in knote_drop_detached()
2762 kn->kn_fp = NULL; in knote_drop_detached()
2764 kqueue_fo_release(kn->kn_kevent.filter); in knote_drop_detached()
2765 kn->kn_fop = NULL; in knote_drop_detached()
2772 struct kqueue *kq = kn->kn_kq; in knote_enqueue()
2774 KQ_OWNED(kn->kn_kq); in knote_enqueue()
2775 KASSERT((kn->kn_status & KN_QUEUED) == 0, ("knote already queued")); in knote_enqueue()
2777 TAILQ_INSERT_TAIL(&kq->kq_head, kn, kn_tqe); in knote_enqueue()
2778 kn->kn_status |= KN_QUEUED; in knote_enqueue()
2779 kq->kq_count++; in knote_enqueue()
2786 struct kqueue *kq = kn->kn_kq; in knote_dequeue()
2788 KQ_OWNED(kn->kn_kq); in knote_dequeue()
2789 KASSERT(kn->kn_status & KN_QUEUED, ("knote not queued")); in knote_dequeue()
2791 TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe); in knote_dequeue()
2792 kn->kn_status &= ~KN_QUEUED; in knote_dequeue()
2793 kq->kq_count--; in knote_dequeue()
2872 if ((kn_status & b->kn_status_bit) != 0) in knote_status_export()
2873 res |= b->knt_status_bit; in knote_status_export()
2888 if (kn->kn_status == KN_MARKER) in kern_proc_kqueue_report_one()
2893 memcpy(&kin.knt_event, &kn->kn_kevent, sizeof(struct kevent)); in kern_proc_kqueue_report_one()
2894 kin.knt_status = knote_status_export(kn->kn_status); in kern_proc_kqueue_report_one()
2897 if (kn->kn_fop->f_userdump != NULL) in kern_proc_kqueue_report_one()
2898 (void)kn->kn_fop->f_userdump(p, kn, &kin); in kern_proc_kqueue_report_one()
2920 for (i = 0; i < kq->kq_knlistsize; i++) { in kern_proc_kqueue_report()
2921 SLIST_FOREACH(kn, &kq->kq_knlist[i], kn_link) { in kern_proc_kqueue_report()
2928 if (kq->kq_knhashmask == 0) in kern_proc_kqueue_report()
2930 for (i = 0; i <= kq->kq_knhashmask; i++) { in kern_proc_kqueue_report()
2931 SLIST_FOREACH(kn, &kq->kq_knhash[i], kn_link) { in kern_proc_kqueue_report()
2954 if (fp->f_type != DTYPE_KQUEUE) in kern_proc_kqueues_out1_cb()
2957 kq = fp->f_data; in kern_proc_kqueues_out1_cb()
2958 return (kern_proc_kqueue_report(a->s, p, fd, kq, a->compat32)); in kern_proc_kqueues_out1_cb()
2980 if (maxlen == -1 || maxlen == 0) in kern_proc_kqueues_out()
2984 s = sbuf_new(&sm, NULL, sb_len, maxlen == -1 ? SBUF_AUTOEXTEND : in kern_proc_kqueues_out()
2989 sbuf_bcat(sb, sbuf_data(s), MIN(sbuf_len(s), maxlen == -1 ? in kern_proc_kqueues_out()
3006 if (fp->f_type != DTYPE_KQUEUE) { in sysctl_kern_proc_kqueue_one()
3009 kq = fp->f_data; in sysctl_kern_proc_kqueue_one()