diff options
author | jlemon <jlemon@FreeBSD.org> | 2001-07-19 18:34:40 +0000 |
---|---|---|
committer | jlemon <jlemon@FreeBSD.org> | 2001-07-19 18:34:40 +0000 |
commit | 6279f096ec23ca04189be5522d4212796a04b454 (patch) | |
tree | e67b49dd81c51656cadaac5d9ca2b48319c1a244 /sys/kern/kern_event.c | |
parent | 6f7c5181731f58ff7ae4d6a63b2051dc15195f81 (diff) | |
download | FreeBSD-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.c | 68 |
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) { |