* Defer the delivery of SIGSTOP for the current thread, according to * the requested mode. Returns previous flags, which must be restored * by sigallowstop(). * * TDF_SBDRY, TDF_SEINTR, and TDF_SERESTART flags are only set and * cleared by the current thread, which allow the lock-less read-only * accesses below. */
| 2771 | * accesses below. |
| 2772 | */ |
| 2773 | int |
| 2774 | sigdeferstop_impl(int mode) |
| 2775 | { |
| 2776 | struct thread *td; |
| 2777 | int cflags, nflags; |
| 2778 | |
| 2779 | td = curthread; |
| 2780 | cflags = sigdeferstop_curr_flags(td->td_flags); |
| 2781 | switch (mode) { |
| 2782 | case SIGDEFERSTOP_NOP: |
| 2783 | nflags = cflags; |
| 2784 | break; |
| 2785 | case SIGDEFERSTOP_OFF: |
| 2786 | nflags = 0; |
| 2787 | break; |
| 2788 | case SIGDEFERSTOP_SILENT: |
| 2789 | nflags = (cflags | TDF_SBDRY) & ~(TDF_SEINTR | TDF_SERESTART); |
| 2790 | break; |
| 2791 | case SIGDEFERSTOP_EINTR: |
| 2792 | nflags = (cflags | TDF_SBDRY | TDF_SEINTR) & ~TDF_SERESTART; |
| 2793 | break; |
| 2794 | case SIGDEFERSTOP_ERESTART: |
| 2795 | nflags = (cflags | TDF_SBDRY | TDF_SERESTART) & ~TDF_SEINTR; |
| 2796 | break; |
| 2797 | default: |
| 2798 | panic("sigdeferstop: invalid mode %x", mode); |
| 2799 | break; |
| 2800 | } |
| 2801 | if (cflags == nflags) |
| 2802 | return (SIGDEFERSTOP_VAL_NCHG); |
| 2803 | thread_lock(td); |
| 2804 | td->td_flags = (td->td_flags & ~cflags) | nflags; |
| 2805 | thread_unlock(td); |
| 2806 | return (cflags); |
| 2807 | } |
| 2808 | |
| 2809 | /* |
| 2810 | * Restores the STOP handling mode, typically permitting the delivery |
no test coverage detected