Page MenuHomeFreeBSD

D15778.id43656.diff
No OneTemporary

D15778.id43656.diff

Index: sys/kern/kern_event.c
===================================================================
--- sys/kern/kern_event.c
+++ sys/kern/kern_event.c
@@ -162,6 +162,8 @@
static void filt_timerexpire(void *knx);
static int filt_timerattach(struct knote *kn);
static void filt_timerdetach(struct knote *kn);
+static void filt_timerstart(struct knote *kn, sbintime_t to);
+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);
static void filt_userdetach(struct knote *kn);
@@ -673,6 +675,8 @@
struct callout c;
sbintime_t next; /* next timer event fires at */
sbintime_t to; /* precalculated timer period, 0 for abs */
+ intptr_t sdata; /* Saved data */
+ int sfflags; /* Saved fflags */
};
static void
@@ -699,12 +703,10 @@
* data contains amount of time to sleep
*/
static int
-filt_timerattach(struct knote *kn)
+filt_timervalidate(struct knote *kn, sbintime_t *to)
{
- struct kq_timer_cb_data *kc;
struct bintime bt;
- sbintime_t to, sbt;
- unsigned int ncallouts;
+ sbintime_t sbt;
if (kn->kn_sdata < 0)
return (EINVAL);
@@ -714,14 +716,28 @@
if ((kn->kn_sfflags & ~(NOTE_TIMER_PRECMASK | NOTE_ABSTIME)) != 0)
return (EINVAL);
- to = timer2sbintime(kn->kn_sdata, kn->kn_sfflags);
+ *to = timer2sbintime(kn->kn_sdata, kn->kn_sfflags);
if ((kn->kn_sfflags & NOTE_ABSTIME) != 0) {
getboottimebin(&bt);
sbt = bttosbt(bt);
to -= sbt;
}
- if (to < 0)
+ if (*to < 0)
return (EINVAL);
+ return (0);
+}
+
+static int
+filt_timerattach(struct knote *kn)
+{
+ struct kq_timer_cb_data *kc;
+ sbintime_t to;
+ unsigned int ncallouts;
+ int error;
+
+ error = filt_timervalidate(kn, &to);
+ if (error != 0)
+ return (error);
do {
ncallouts = kq_ncallouts;
@@ -734,6 +750,17 @@
kn->kn_status &= ~KN_DETACHED; /* knlist_add clears it */
kn->kn_ptr.p_v = kc = malloc(sizeof(*kc), M_KQUEUE, M_WAITOK);
callout_init(&kc->c, 1);
+ filt_timerstart(kn, to);
+
+ return (0);
+}
+
+static void
+filt_timerstart(struct knote *kn, sbintime_t to)
+{
+ struct kq_timer_cb_data *kc;
+
+ kc = kn->kn_ptr.p_v;
if ((kn->kn_sfflags & NOTE_ABSTIME) != 0) {
kc->next = to;
kc->to = 0;
@@ -741,10 +768,10 @@
kc->next = to + sbinuptime();
kc->to = to;
}
+ kc->sdata = kn->kn_sdata;
+ kc->sfflags = kn->kn_sfflags;
callout_reset_sbt_on(&kc->c, kc->next, 0, filt_timerexpire, kn,
PCPU_GET(cpuid), C_ABSOLUTE);
-
- return (0);
}
static void
@@ -764,6 +791,21 @@
static int
filt_timer(struct knote *kn, long hint)
{
+ struct kq_timer_cb_data *kc;
+ sbintime_t to;
+ int error;
+
+ kc = kn->kn_ptr.p_v;
+ /* Handle re-added timers that update data/fflags */
+ if ((kc->sdata != kn->kn_sdata || kc->sfflags != kn->kn_sfflags) &&
+ ((kn->kn_flags & EV_ONESHOT) == 0 || kn->kn_data == 0)) {
+ error = filt_timervalidate(kn, &to);
+ if (error != 0) {
+ kn->kn_flags |= EV_ERROR;
+ kn->kn_data = error;
+ } else
+ filt_timerstart(kn, to);
+ }
return (kn->kn_data != 0);
}

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 7, 2:59 PM (19 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31038380
Default Alt Text
D15778.id43656.diff (2 KB)

Event Timeline