* procdesc_exit() - notify a process descriptor that its process is exiting. * We use the proctree_lock to ensure that process exit either happens * strictly before or strictly after a concurrent call to procdesc_close(). */
| 284 | * strictly before or strictly after a concurrent call to procdesc_close(). |
| 285 | */ |
| 286 | int |
| 287 | procdesc_exit(struct proc *p) |
| 288 | { |
| 289 | struct procdesc *pd; |
| 290 | |
| 291 | sx_assert(&proctree_lock, SA_XLOCKED); |
| 292 | PROC_LOCK_ASSERT(p, MA_OWNED); |
| 293 | KASSERT(p->p_procdesc != NULL, ("procdesc_exit: p_procdesc NULL")); |
| 294 | |
| 295 | pd = p->p_procdesc; |
| 296 | |
| 297 | PROCDESC_LOCK(pd); |
| 298 | KASSERT((pd->pd_flags & PDF_CLOSED) == 0 || p->p_pptr == p->p_reaper, |
| 299 | ("procdesc_exit: closed && parent not reaper")); |
| 300 | |
| 301 | pd->pd_flags |= PDF_EXITED; |
| 302 | pd->pd_xstat = KW_EXITCODE(p->p_xexit, p->p_xsig); |
| 303 | |
| 304 | /* |
| 305 | * If the process descriptor has been closed, then we have nothing |
| 306 | * to do; return 1 so that init will get SIGCHLD and do the reaping. |
| 307 | * Clean up the procdesc now rather than letting it happen during |
| 308 | * that reap. |
| 309 | */ |
| 310 | if (pd->pd_flags & PDF_CLOSED) { |
| 311 | PROCDESC_UNLOCK(pd); |
| 312 | pd->pd_proc = NULL; |
| 313 | p->p_procdesc = NULL; |
| 314 | procdesc_free(pd); |
| 315 | return (1); |
| 316 | } |
| 317 | if (pd->pd_flags & PDF_SELECTED) { |
| 318 | pd->pd_flags &= ~PDF_SELECTED; |
| 319 | selwakeup(&pd->pd_selinfo); |
| 320 | } |
| 321 | KNOTE_LOCKED(&pd->pd_selinfo.si_note, NOTE_EXIT); |
| 322 | PROCDESC_UNLOCK(pd); |
| 323 | return (0); |
| 324 | } |
| 325 | |
| 326 | /* |
| 327 | * When a process descriptor is reaped, perhaps as a result of close() or |
no test coverage detected