-.\" $OpenBSD: kqueue.2,v 1.43 2020/11/14 10:16:15 jmc Exp $
+.\" $OpenBSD: kqueue.2,v 1.44 2021/04/22 15:30:12 visa Exp $
.\"
.\" Copyright (c) 2000 Jonathan Lemon
.\" All rights reserved.
.\"
.\" $FreeBSD: src/lib/libc/sys/kqueue.2,v 1.18 2001/02/14 08:48:35 guido Exp $
.\"
-.Dd $Mdocdate: November 14 2020 $
+.Dd $Mdocdate: April 22 2021 $
.Dt KQUEUE 2
.Os
.Sh NAME
This filter automatically sets the
.Dv EV_CLEAR
flag internally.
+.Pp
+If an existing timer is re-added, the existing timer and related pending events
+will be cancelled.
+The timer will be re-started using the timeout period
+.Fa data .
.It Dv EVFILT_DEVICE
Takes a descriptor as the identifier and the events to watch for in
.Fa fflags ,
-/* $OpenBSD: kern_event.c,v 1.162 2021/02/27 13:43:16 visa Exp $ */
+/* $OpenBSD: kern_event.c,v 1.163 2021/04/22 15:30:12 visa Exp $ */
/*-
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
void filt_timerexpire(void *knx);
int filt_timerattach(struct knote *kn);
void filt_timerdetach(struct knote *kn);
-int filt_timer(struct knote *kn, long hint);
+int filt_timermodify(struct kevent *kev, struct knote *kn);
+int filt_timerprocess(struct knote *kn, struct kevent *kev);
void filt_seltruedetach(struct knote *kn);
const struct filterops kqread_filtops = {
.f_flags = 0,
.f_attach = filt_timerattach,
.f_detach = filt_timerdetach,
- .f_event = filt_timer,
+ .f_event = NULL,
+ .f_modify = filt_timermodify,
+ .f_process = filt_timerprocess,
};
struct pool knote_pool;
struct timeout *to;
to = (struct timeout *)kn->kn_hook;
- timeout_del(to);
+ timeout_del_barrier(to);
free(to, M_KEVENT, sizeof(*to));
kq_ntimeouts--;
}
int
-filt_timer(struct knote *kn, long hint)
+filt_timermodify(struct kevent *kev, struct knote *kn)
+{
+ struct timeout *to = kn->kn_hook;
+ int s;
+
+ /* Reset the timer. Any pending events are discarded. */
+
+ timeout_del_barrier(to);
+
+ s = splhigh();
+ if (kn->kn_status & KN_QUEUED)
+ knote_dequeue(kn);
+ kn->kn_status &= ~KN_ACTIVE;
+ splx(s);
+
+ kn->kn_data = 0;
+ knote_modify(kev, kn);
+ /* Reinit timeout to invoke tick adjustment again. */
+ timeout_set(to, filt_timerexpire, kn);
+ filt_timer_timeout_add(kn);
+
+ return (0);
+}
+
+int
+filt_timerprocess(struct knote *kn, struct kevent *kev)
{
- return (kn->kn_data != 0);
+ int active, s;
+
+ s = splsoftclock();
+ active = (kn->kn_data != 0);
+ if (active)
+ knote_submit(kn, kev);
+ splx(s);
+
+ return (active);
}