summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_event.c
diff options
context:
space:
mode:
authorjlemon <jlemon@FreeBSD.org>2001-07-19 18:34:40 +0000
committerjlemon <jlemon@FreeBSD.org>2001-07-19 18:34:40 +0000
commit6279f096ec23ca04189be5522d4212796a04b454 (patch)
treee67b49dd81c51656cadaac5d9ca2b48319c1a244 /sys/kern/kern_event.c
parent6f7c5181731f58ff7ae4d6a63b2051dc15195f81 (diff)
downloadFreeBSD-src-6279f096ec23ca04189be5522d4212796a04b454.zip
FreeBSD-src-6279f096ec23ca04189be5522d4212796a04b454.tar.gz
Introduce EVFILT_TIMER, which allows a process to establish an
arbitrary number of timers, both oneshot and periodic. Repeatedly reminded to commit by: jayanth Reviewed by: peter (a while back)
Diffstat (limited to 'sys/kern/kern_event.c')
-rw-r--r--sys/kern/kern_event.c68
1 files changed, 66 insertions, 2 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 4f8b61b..208899c 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -90,13 +90,19 @@ static int filt_procattach(struct knote *kn);
static void filt_procdetach(struct knote *kn);
static int filt_proc(struct knote *kn, long hint);
static int filt_fileattach(struct knote *kn);
+static void filt_timerexpire(void *knx);
+static int filt_timerattach(struct knote *kn);
+static void filt_timerdetach(struct knote *kn);
+static int filt_timer(struct knote *kn, long hint);
+static struct filterops file_filtops =
+ { 1, filt_fileattach, NULL, NULL };
static struct filterops kqread_filtops =
{ 1, NULL, filt_kqdetach, filt_kqueue };
static struct filterops proc_filtops =
{ 0, filt_procattach, filt_procdetach, filt_proc };
-static struct filterops file_filtops =
- { 1, filt_fileattach, NULL, NULL };
+static struct filterops timer_filtops =
+ { 0, filt_timerattach, filt_timerdetach, filt_timer };
static vm_zone_t knote_zone;
@@ -122,6 +128,7 @@ static struct filterops *sysfilt_ops[] = {
&file_filtops, /* EVFILT_VNODE */
&proc_filtops, /* EVFILT_PROC */
&sig_filtops, /* EVFILT_SIGNAL */
+ &timer_filtops, /* EVFILT_TIMER */
};
static int
@@ -267,6 +274,63 @@ filt_proc(struct knote *kn, long hint)
return (kn->kn_fflags != 0);
}
+static void
+filt_timerexpire(void *knx)
+{
+ struct knote *kn = knx;
+ struct callout_handle ch;
+ struct timeval tv;
+ int tticks;
+
+ kn->kn_data++;
+ KNOTE_ACTIVATE(kn);
+
+ if ((kn->kn_flags & EV_ONESHOT) == 0) {
+ tv.tv_sec = kn->kn_sdata / 1000;
+ tv.tv_usec = (kn->kn_sdata % 1000) * 1000;
+ tticks = tvtohz(&tv);
+ ch = timeout(filt_timerexpire, kn, tticks);
+ kn->kn_hook = (caddr_t)ch.callout;
+ }
+}
+
+/*
+ * data contains amount of time to sleep, in milliseconds
+ */
+static int
+filt_timerattach(struct knote *kn)
+{
+ struct callout_handle ch;
+ struct timeval tv;
+ int tticks;
+
+ tv.tv_sec = kn->kn_sdata / 1000;
+ tv.tv_usec = (kn->kn_sdata % 1000) * 1000;
+ tticks = tvtohz(&tv);
+
+ kn->kn_flags |= EV_CLEAR; /* automatically set */
+ ch = timeout(filt_timerexpire, kn, tticks);
+ kn->kn_hook = (caddr_t)ch.callout;
+
+ return (0);
+}
+
+static void
+filt_timerdetach(struct knote *kn)
+{
+ struct callout_handle ch;
+
+ ch.callout = (struct callout *)kn->kn_hook;
+ untimeout(filt_timerexpire, kn, ch);
+}
+
+static int
+filt_timer(struct knote *kn, long hint)
+{
+
+ return (kn->kn_data != 0);
+}
+
int
kqueue(struct proc *p, struct kqueue_args *uap)
{
OpenPOWER on IntegriCloud