| 775 | } |
| 776 | |
| 777 | void |
| 778 | fork_rfppwait(struct thread *td) |
| 779 | { |
| 780 | struct proc *p, *p2; |
| 781 | |
| 782 | MPASS(td->td_pflags & TDP_RFPPWAIT); |
| 783 | |
| 784 | p = td->td_proc; |
| 785 | /* |
| 786 | * Preserve synchronization semantics of vfork. If |
| 787 | * waiting for child to exec or exit, fork set |
| 788 | * P_PPWAIT on child, and there we sleep on our proc |
| 789 | * (in case of exit). |
| 790 | * |
| 791 | * Do it after the ptracestop() above is finished, to |
| 792 | * not block our debugger until child execs or exits |
| 793 | * to finish vfork wait. |
| 794 | */ |
| 795 | td->td_pflags &= ~TDP_RFPPWAIT; |
| 796 | p2 = td->td_rfppwait_p; |
| 797 | again: |
| 798 | PROC_LOCK(p2); |
| 799 | while (p2->p_flag & P_PPWAIT) { |
| 800 | PROC_LOCK(p); |
| 801 | if (thread_suspend_check_needed()) { |
| 802 | PROC_UNLOCK(p2); |
| 803 | thread_suspend_check(0); |
| 804 | PROC_UNLOCK(p); |
| 805 | goto again; |
| 806 | } else { |
| 807 | PROC_UNLOCK(p); |
| 808 | } |
| 809 | cv_timedwait(&p2->p_pwait, &p2->p_mtx, hz); |
| 810 | } |
| 811 | PROC_UNLOCK(p2); |
| 812 | |
| 813 | if (td->td_dbgflags & TDB_VFORK) { |
| 814 | PROC_LOCK(p); |
| 815 | if (p->p_ptevents & PTRACE_VFORK) |
| 816 | ptracestop(td, SIGTRAP, NULL); |
| 817 | td->td_dbgflags &= ~TDB_VFORK; |
| 818 | PROC_UNLOCK(p); |
| 819 | } |
| 820 | } |
| 821 | |
| 822 | int |
| 823 | fork1(struct thread *td, struct fork_req *fr) |
no test coverage detected