Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_event.c
| Show First 20 Lines • Show All 439 Lines • ▼ Show 20 Lines | |||||||||
| static int | static int | ||||||||
| filt_procattach(struct knote *kn) | filt_procattach(struct knote *kn) | ||||||||
| { | { | ||||||||
| struct proc *p; | struct proc *p; | ||||||||
| int error; | int error; | ||||||||
| bool exiting, immediate; | bool exiting, immediate; | ||||||||
| exiting = immediate = false; | exiting = immediate = false; | ||||||||
| if (kn->kn_sfflags & NOTE_EXIT) | if (kn->kn_sfflags & (NOTE_EXIT | NOTE_REAP)) | ||||||||
kibUnsubmitted Not Done Inline Actions
kib: | |||||||||
Done Inline ActionsBetter to do a sweep later. des: Better to do a sweep later. | |||||||||
| p = pfind_any(kn->kn_id); | p = pfind_any(kn->kn_id); | ||||||||
| else | else | ||||||||
| p = pfind(kn->kn_id); | p = pfind(kn->kn_id); | ||||||||
| if (p == NULL) | if (p == NULL) | ||||||||
| return (ESRCH); | return (ESRCH); | ||||||||
| if (p->p_flag & P_WEXIT) | if (p->p_flag & P_WEXIT) | ||||||||
| exiting = true; | exiting = true; | ||||||||
| if ((error = p_cansee(curthread, p))) { | if ((error = p_cansee(curthread, p))) { | ||||||||
| PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||||||
| return (error); | return (error); | ||||||||
| } | } | ||||||||
| kn->kn_ptr.p_proc = p; | kn->kn_ptr.p_proc = p; | ||||||||
| kn->kn_flags |= EV_CLEAR; /* automatically set */ | kn->kn_flags |= EV_CLEAR; /* automatically set */ | ||||||||
| /* | /* | ||||||||
| * Internal flag indicating registration done by kernel for the | * Internal flag indicating registration done by kernel for the | ||||||||
| * purposes of getting a NOTE_CHILD notification. | * purposes of getting a NOTE_CHILD notification. | ||||||||
| */ | */ | ||||||||
| if (kn->kn_flags & EV_FLAG2) { | if (kn->kn_flags & EV_FLAG2) { | ||||||||
| kn->kn_flags &= ~EV_FLAG2; | kn->kn_flags &= ~EV_FLAG2; | ||||||||
| kn->kn_data = kn->kn_sdata; /* ppid */ | kn->kn_data = kn->kn_sdata; /* ppid */ | ||||||||
| kn->kn_fflags = NOTE_CHILD; | kn->kn_fflags = NOTE_CHILD; | ||||||||
| kn->kn_sfflags &= ~(NOTE_EXIT | NOTE_EXEC | NOTE_FORK); | kn->kn_sfflags &= ~NOTE_PCTRLMASK; | ||||||||
Not Done Inline ActionsI think that EVFILT_PROC and EVFILT_PROCDESC need a separate PCTRLMASKs, I will handle this afterward. kib: I think that EVFILT_PROC and EVFILT_PROCDESC need a separate PCTRLMASKs, I will handle this… | |||||||||
| immediate = true; /* Force immediate activation of child note. */ | immediate = true; /* Force immediate activation of child note. */ | ||||||||
| } | } | ||||||||
| /* | /* | ||||||||
| * Internal flag indicating registration done by kernel (for other than | * Internal flag indicating registration done by kernel (for other than | ||||||||
| * NOTE_CHILD). | * NOTE_CHILD). | ||||||||
| */ | */ | ||||||||
| if (kn->kn_flags & EV_FLAG1) { | if (kn->kn_flags & EV_FLAG1) { | ||||||||
| kn->kn_flags &= ~EV_FLAG1; | kn->kn_flags &= ~EV_FLAG1; | ||||||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | filt_proc(struct knote *kn, long hint) | ||||||||
| /* Mask off extra data. */ | /* Mask off extra data. */ | ||||||||
| event = (u_int)hint & NOTE_PCTRLMASK; | event = (u_int)hint & NOTE_PCTRLMASK; | ||||||||
| /* If the user is interested in this event, record it. */ | /* If the user is interested in this event, record it. */ | ||||||||
| if ((kn->kn_sfflags & event) != 0) | if ((kn->kn_sfflags & event) != 0) | ||||||||
| kn->kn_fflags |= kn->kn_sfflags & event; | kn->kn_fflags |= kn->kn_sfflags & event; | ||||||||
| /* Report exit status */ | |||||||||
| if ((kn->kn_fflags & NOTE_EXIT) != 0) | |||||||||
| kn->kn_data = KW_EXITCODE(p->p_xexit, p->p_xsig); | |||||||||
| /* Process is gone, so flag the event as finished. */ | /* Process is gone, so flag the event as finished. */ | ||||||||
| if ((event & NOTE_EXIT) != 0) { | if ((event & NOTE_REAP) != 0 || | ||||||||
| ((event & NOTE_EXIT) != 0 && (kn->kn_sfflags & NOTE_REAP) == 0)) { | |||||||||
| kn->kn_flags |= EV_EOF | EV_ONESHOT; | kn->kn_flags |= EV_EOF | EV_ONESHOT; | ||||||||
| kn->kn_ptr.p_proc = NULL; | kn->kn_ptr.p_proc = NULL; | ||||||||
| if (kn->kn_fflags & NOTE_EXIT) | |||||||||
| kn->kn_data = KW_EXITCODE(p->p_xexit, p->p_xsig); | |||||||||
| if (kn->kn_fflags == 0) | if (kn->kn_fflags == 0) | ||||||||
| kn->kn_flags |= EV_DROP; | kn->kn_flags |= EV_DROP; | ||||||||
| return (1); | return (1); | ||||||||
| } | } | ||||||||
| return (kn->kn_fflags != 0); | return (kn->kn_fflags != 0); | ||||||||
| } | } | ||||||||
| ▲ Show 20 Lines • Show All 1,689 Lines • ▼ Show 20 Lines | if ((kn->kn_flags & EV_DROP) == EV_DROP) { | ||||||||
| KQ_GLOBAL_LOCK(&kq_global, haskqglobal); | KQ_GLOBAL_LOCK(&kq_global, haskqglobal); | ||||||||
| knl = kn_list_lock(kn); | knl = kn_list_lock(kn); | ||||||||
| if (kn->kn_fop->f_event(kn, 0) == 0) { | if (kn->kn_fop->f_event(kn, 0) == 0) { | ||||||||
| KQ_LOCK(kq); | KQ_LOCK(kq); | ||||||||
| KQ_GLOBAL_UNLOCK(&kq_global, haskqglobal); | KQ_GLOBAL_UNLOCK(&kq_global, haskqglobal); | ||||||||
| kn->kn_status &= ~(KN_QUEUED | KN_ACTIVE | | kn->kn_status &= ~(KN_QUEUED | KN_ACTIVE | | ||||||||
| KN_SCAN); | KN_SCAN); | ||||||||
| kn_leave_flux(kn); | kn_leave_flux(kn); | ||||||||
| kq->kq_count--; | kq->kq_count--; | ||||||||
Done Inline ActionsWhy move this out of the flux segment? kevans: Why move this out of the flux segment? | |||||||||
Done Inline ActionsWe set the KN_SCAN bit before entering flux, we should clear it after leaving flux. I suppose it makes no difference in practice since in both cases kq is locked throughout, but this seemed cleaner to me. des: We set the `KN_SCAN` bit before entering flux, we should clear it after leaving flux. I suppose… | |||||||||
| kn_list_unlock(knl); | kn_list_unlock(knl); | ||||||||
| influx = 1; | influx = 1; | ||||||||
| continue; | continue; | ||||||||
| } | } | ||||||||
| touch = (!kn->kn_fop->f_isfd && | touch = (!kn->kn_fop->f_isfd && | ||||||||
| kn->kn_fop->f_touch != NULL); | kn->kn_fop->f_touch != NULL); | ||||||||
| if (touch) | if (touch) | ||||||||
| kn->kn_fop->f_touch(kn, kevp, EVENT_PROCESS); | kn->kn_fop->f_touch(kn, kevp, EVENT_PROCESS); | ||||||||
| ▲ Show 20 Lines • Show All 1,176 Lines • Show Last 20 Lines | |||||||||