| 153 | } |
| 154 | |
| 155 | U32 KThread::signal(U32 signal, bool wait) { |
| 156 | if (signal==0) { |
| 157 | return 0; |
| 158 | } |
| 159 | BOXEDWINE_CRITICAL_SECTION_WITH_CONDITION(this->sigWaitCond); |
| 160 | if (this->sigWaitMask & signal) { |
| 161 | this->foundWaitSignal = signal; |
| 162 | BOXEDWINE_CONDITION_SIGNAL(this->sigWaitCond); |
| 163 | return 0; |
| 164 | } |
| 165 | memset(process->sigActions[signal].sigInfo, 0, sizeof(process->sigActions[signal].sigInfo)); |
| 166 | process->sigActions[signal].sigInfo[0] = signal; |
| 167 | process->sigActions[signal].sigInfo[2] = K_SI_USER; |
| 168 | process->sigActions[signal].sigInfo[3] = process->id; |
| 169 | process->sigActions[signal].sigInfo[4] = process->userId; |
| 170 | |
| 171 | if (signal == K_SIGKILL || signal == K_SIGSTOP || readyForSignal(signal)) { |
| 172 | // don't return -K_WAIT, we don't want to re-enter tgkill, instead we will return 0 once the thread wakes up |
| 173 | |
| 174 | // must set CPU state before runSignal since it will be stored |
| 175 | if (this==KThread::currentThread()) { |
| 176 | this->cpu->reg[0].u32 = 0; |
| 177 | this->cpu->eip.u32+=2; |
| 178 | } |
| 179 | #ifdef BOXEDWINE_MULTI_THREADED |
| 180 | else { |
| 181 | // :TODO: how to interrupt the thread (the current approache assumes the thread will yield to the signal) |
| 182 | { |
| 183 | bool handled = false; |
| 184 | |
| 185 | BOXEDWINE_CONDITION cond = waitingCond; |
| 186 | if (signal == K_SIGQUIT && cond) { |
| 187 | BOXEDWINE_CRITICAL_SECTION_WITH_CONDITION(cond); |
| 188 | if (waitingCond) { |
| 189 | this->startSignal = true; |
| 190 | this->runSignal(K_SIGQUIT, -1, 0); |
| 191 | BOXEDWINE_CONDITION_SIGNAL(cond); |
| 192 | handled = true; |
| 193 | } |
| 194 | } |
| 195 | if (!handled) { |
| 196 | BOXEDWINE_CRITICAL_SECTION_WITH_MUTEX(this->pendingSignalsMutex); |
| 197 | this->pendingSignals |= ((U64)1 << (signal - 1)); |
| 198 | } |
| 199 | } |
| 200 | if (wait && !this->terminating) { |
| 201 | BOXEDWINE_CONDITION c = this->waitingCond; |
| 202 | if (c) { |
| 203 | BOXEDWINE_CRITICAL_SECTION_WITH_CONDITION(c); |
| 204 | BOXEDWINE_CONDITION_SIGNAL_ALL(c); |
| 205 | } |
| 206 | BOXEDWINE_CRITICAL_SECTION_WITH_CONDITION(this->waitingForSignalToEndCond); |
| 207 | BOXEDWINE_CONDITION_WAIT_TIMEOUT(this->waitingForSignalToEndCond, 1000); |
| 208 | } |
| 209 | return 0; |
| 210 | } |
| 211 | #endif |
| 212 | this->runSignal(signal, -1, 0); |
no test coverage detected