* Abort a thread as if an interrupt had occurred. Only abort * interruptible waits (unfortunately it isn't safe to abort others). * * Requires thread lock on entry, releases on return. */
| 1093 | * Requires thread lock on entry, releases on return. |
| 1094 | */ |
| 1095 | int |
| 1096 | sleepq_abort(struct thread *td, int intrval) |
| 1097 | { |
| 1098 | struct sleepqueue *sq; |
| 1099 | const void *wchan; |
| 1100 | |
| 1101 | THREAD_LOCK_ASSERT(td, MA_OWNED); |
| 1102 | MPASS(TD_ON_SLEEPQ(td)); |
| 1103 | MPASS(td->td_flags & TDF_SINTR); |
| 1104 | MPASS(intrval == EINTR || intrval == ERESTART); |
| 1105 | |
| 1106 | /* |
| 1107 | * If the TDF_TIMEOUT flag is set, just leave. A |
| 1108 | * timeout is scheduled anyhow. |
| 1109 | */ |
| 1110 | if (td->td_flags & TDF_TIMEOUT) { |
| 1111 | thread_unlock(td); |
| 1112 | return (0); |
| 1113 | } |
| 1114 | |
| 1115 | CTR3(KTR_PROC, "sleepq_abort: thread %p (pid %ld, %s)", |
| 1116 | (void *)td, (long)td->td_proc->p_pid, (void *)td->td_name); |
| 1117 | td->td_intrval = intrval; |
| 1118 | |
| 1119 | /* |
| 1120 | * If the thread has not slept yet it will find the signal in |
| 1121 | * sleepq_catch_signals() and call sleepq_resume_thread. Otherwise |
| 1122 | * we have to do it here. |
| 1123 | */ |
| 1124 | if (!TD_IS_SLEEPING(td)) { |
| 1125 | thread_unlock(td); |
| 1126 | return (0); |
| 1127 | } |
| 1128 | wchan = td->td_wchan; |
| 1129 | MPASS(wchan != NULL); |
| 1130 | sq = sleepq_lookup(wchan); |
| 1131 | MPASS(sq != NULL); |
| 1132 | |
| 1133 | /* Thread is asleep on sleep queue sq, so wake it up. */ |
| 1134 | return (sleepq_resume_thread(sq, td, 0, 0)); |
| 1135 | } |
| 1136 | |
| 1137 | void |
| 1138 | sleepq_chains_remove_matching(bool (*matches)(struct thread *)) |
no test coverage detected