diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2025-08-20 19:06:05 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2025-10-18 05:12:36 +0000 |
| commit | c0e70e7b97dcfcbeedfdfbacf1543b756a616a18 (patch) | |
| tree | 999118d4a196d1996ae769ee65492b2b358a457a | |
| parent | b11289f87123f8ae06fc70bc70d26a25d4356a65 (diff) | |
| -rw-r--r-- | sys/kern/kern_event.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 1f3030995ec6..4fd495fa1ec8 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -179,6 +179,7 @@ static void filt_timerdetach(struct knote *kn); static void filt_timerstart(struct knote *kn, sbintime_t to); static void filt_timertouch(struct knote *kn, struct kevent *kev, u_long type); +static int filt_timercopy(struct knote *kn, struct proc *p1); static int filt_timervalidate(struct knote *kn, sbintime_t *to); static int filt_timer(struct knote *kn, long hint); static int filt_userattach(struct knote *kn); @@ -215,6 +216,7 @@ static const struct filterops timer_filtops = { .f_detach = filt_timerdetach, .f_event = filt_timer, .f_touch = filt_timertouch, + .f_copy = filt_timercopy, }; static const struct filterops user_filtops = { .f_attach = filt_userattach, @@ -943,6 +945,30 @@ filt_timerattach(struct knote *kn) return (0); } +static int +filt_timercopy(struct knote *kn, struct proc *p) +{ + struct kq_timer_cb_data *kc_src, *kc; + + if (atomic_fetchadd_int(&kq_ncallouts, 1) + 1 > kq_calloutmax) { + atomic_subtract_int(&kq_ncallouts, 1); + return (ENOMEM); + } + + kn->kn_status &= ~KN_DETACHED; + kc_src = kn->kn_ptr.p_v; + kn->kn_ptr.p_v = kc = malloc(sizeof(*kc), M_KQUEUE, M_WAITOK); + kc->kn = kn; + kc->p = p; + kc->flags = kc_src->flags & ~KQ_TIMER_CB_ENQUEUED; + kc->next = kc_src->next; + kc->to = kc_src->to; + kc->cpuid = PCPU_GET(cpuid); + callout_init(&kc->c, 1); + kqtimer_sched_callout(kc); + return (0); +} + static void filt_timerstart(struct knote *kn, sbintime_t to) { |
