Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_event.c
Show First 20 Lines • Show All 155 Lines • ▼ Show 20 Lines | |||||
static void filt_kqdetach(struct knote *kn); | static void filt_kqdetach(struct knote *kn); | ||||
static int filt_kqueue(struct knote *kn, long hint); | static int filt_kqueue(struct knote *kn, long hint); | ||||
static int filt_procattach(struct knote *kn); | static int filt_procattach(struct knote *kn); | ||||
static void filt_procdetach(struct knote *kn); | static void filt_procdetach(struct knote *kn); | ||||
static int filt_proc(struct knote *kn, long hint); | static int filt_proc(struct knote *kn, long hint); | ||||
static int filt_fileattach(struct knote *kn); | static int filt_fileattach(struct knote *kn); | ||||
static void filt_timerexpire(void *knx); | static void filt_timerexpire(void *knx); | ||||
static void filt_timerexpire_l(struct knote *kn, bool proc_locked); | |||||
static int filt_timerattach(struct knote *kn); | static int filt_timerattach(struct knote *kn); | ||||
static void filt_timerdetach(struct knote *kn); | static void filt_timerdetach(struct knote *kn); | ||||
static void filt_timerstart(struct knote *kn, sbintime_t to); | static void filt_timerstart(struct knote *kn, sbintime_t to); | ||||
static void filt_timertouch(struct knote *kn, struct kevent *kev, | static void filt_timertouch(struct knote *kn, struct kevent *kev, | ||||
u_long type); | u_long type); | ||||
static int filt_timervalidate(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_timer(struct knote *kn, long hint); | ||||
static int filt_userattach(struct knote *kn); | static int filt_userattach(struct knote *kn); | ||||
▲ Show 20 Lines • Show All 529 Lines • ▼ Show 20 Lines | kqtimer_proc_continue(struct proc *p) | ||||
PROC_LOCK_ASSERT(p, MA_OWNED); | PROC_LOCK_ASSERT(p, MA_OWNED); | ||||
getboottimebin(&bt); | getboottimebin(&bt); | ||||
now = bttosbt(bt); | now = bttosbt(bt); | ||||
TAILQ_FOREACH_SAFE(kc, &p->p_kqtim_stop, link, kc1) { | TAILQ_FOREACH_SAFE(kc, &p->p_kqtim_stop, link, kc1) { | ||||
TAILQ_REMOVE(&p->p_kqtim_stop, kc, link); | TAILQ_REMOVE(&p->p_kqtim_stop, kc, link); | ||||
if (kc->next <= now) | if (kc->next <= now) | ||||
filt_timerexpire(kc->kn); | filt_timerexpire_l(kc->kn, true); | ||||
else | else | ||||
kqtimer_sched_callout(kc); | kqtimer_sched_callout(kc); | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
filt_timerexpire(void *knx) | filt_timerexpire_l(struct knote *kn, bool proc_locked) | ||||
{ | { | ||||
struct knote *kn; | |||||
struct kq_timer_cb_data *kc; | struct kq_timer_cb_data *kc; | ||||
struct proc *p; | struct proc *p; | ||||
sbintime_t now; | sbintime_t now; | ||||
kn = knx; | |||||
kc = kn->kn_ptr.p_v; | kc = kn->kn_ptr.p_v; | ||||
if ((kn->kn_flags & EV_ONESHOT) != 0 || kc->to == 0) { | if ((kn->kn_flags & EV_ONESHOT) != 0 || kc->to == 0) { | ||||
kn->kn_data++; | kn->kn_data++; | ||||
KNOTE_ACTIVATE(kn, 0); | KNOTE_ACTIVATE(kn, 0); | ||||
return; | return; | ||||
} | } | ||||
for (now = sbinuptime(); kc->next <= now; kc->next += kc->to) | for (now = sbinuptime(); kc->next <= now; kc->next += kc->to) | ||||
kn->kn_data++; | kn->kn_data++; | ||||
KNOTE_ACTIVATE(kn, 0); /* XXX - handle locking */ | KNOTE_ACTIVATE(kn, 0); /* XXX - handle locking */ | ||||
/* | /* | ||||
* Initial check for stopped kc->p is racy. It is fine to | * Initial check for stopped kc->p is racy. It is fine to | ||||
* miss the set of the stop flags, at worst we would schedule | * miss the set of the stop flags, at worst we would schedule | ||||
* one more callout. On the other hand, it is not fine to not | * one more callout. On the other hand, it is not fine to not | ||||
* schedule when we we missed clearing of the flags, we | * schedule when we we missed clearing of the flags, we | ||||
* recheck them under the lock and observe consistent state. | * recheck them under the lock and observe consistent state. | ||||
*/ | */ | ||||
p = kc->p; | p = kc->p; | ||||
if (P_SHOULDSTOP(p) || P_KILLED(p)) { | if (P_SHOULDSTOP(p) || P_KILLED(p)) { | ||||
if (!proc_locked) | |||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
if (P_SHOULDSTOP(p) || P_KILLED(p)) { | if (P_SHOULDSTOP(p) || P_KILLED(p)) { | ||||
TAILQ_INSERT_TAIL(&p->p_kqtim_stop, kc, link); | TAILQ_INSERT_TAIL(&p->p_kqtim_stop, kc, link); | ||||
if (!proc_locked) | |||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
return; | return; | ||||
} | } | ||||
if (!proc_locked) | |||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
} | } | ||||
kqtimer_sched_callout(kc); | kqtimer_sched_callout(kc); | ||||
} | |||||
static void | |||||
filt_timerexpire(void *knx) | |||||
{ | |||||
filt_timerexpire_l(knx, false); | |||||
} | } | ||||
/* | /* | ||||
* data contains amount of time to sleep | * data contains amount of time to sleep | ||||
*/ | */ | ||||
static int | static int | ||||
filt_timervalidate(struct knote *kn, sbintime_t *to) | filt_timervalidate(struct knote *kn, sbintime_t *to) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 2,024 Lines • Show Last 20 Lines |