| 714 | } |
| 715 | |
| 716 | bool KThread::runSignals() { |
| 717 | U64 mask = this->inSignal ? this->inSigMask : this->sigMask; |
| 718 | U64 todoProcess = this->process->pendingSignals & ~mask; |
| 719 | U64 todoThread = this->pendingSignals & ~mask; |
| 720 | |
| 721 | // It seems like linux (tiny core 13, maybe libc) sets the sigprocmask to 0x10012A03 K_SIGIO|K_SIGCHLD|K_SIGALRM|K_SIGUSR2|K_SIGUSR1|K_SIGINT|K_SIGHUP |
| 722 | // then it grabs a pthread mutex via compare exchange |
| 723 | // then wine sends a K_SIGQUIT signal to that thread |
| 724 | // the thread dies/exits because of handling SIGKILL without releasing the pthread mutex |
| 725 | // the next thread in the process that asks for the mutex hangs |
| 726 | // |
| 727 | // I only noticed this on multi-thread normal core with win32, I wonder if this is a race condition that normally doesn't happen under faster circumstances |
| 728 | // |
| 729 | // for now I will add this hack |
| 730 | // |
| 731 | // hopefully it won't have any bad side effects and cause other bugs |
| 732 | if ((todoThread & ((U64)1 << (K_SIGQUIT-1))) && (mask & ((U64)1 << (K_SIGIO-1)))) { |
| 733 | todoThread &= ~((U64)1 << (K_SIGQUIT-1)); // don't process SIGKILL now |
| 734 | } |
| 735 | if (todoProcess!=0 || todoThread!=0) { |
| 736 | U32 i; |
| 737 | |
| 738 | for (i=0;i<32;i++) { |
| 739 | if ((todoProcess & ((U64)1 << i))!=0) { |
| 740 | BOXEDWINE_CRITICAL_SECTION_WITH_MUTEX(this->process->pendingSignalsMutex); |
| 741 | if ((this->process->pendingSignals & ((U64)1 << i))!=0 || i + 1 == K_SIGKILL) { // SIGKILL can't be ignored |
| 742 | this->process->pendingSignals &= ~(1 << i); |
| 743 | this->runSignal(i+1, -1, 0); |
| 744 | return true; |
| 745 | } |
| 746 | } |
| 747 | if ((todoThread & ((U64)1 << i))!=0) { |
| 748 | BOXEDWINE_CRITICAL_SECTION_WITH_MUTEX(this->pendingSignalsMutex); |
| 749 | if ((this->pendingSignals & ((U64)1 << i))!=0 || i+1 == K_SIGKILL) { // SIGKILL can't be ignored |
| 750 | this->pendingSignals &= ~(1 << i); |
| 751 | this->runSignal(i+1, -1, 0); |
| 752 | return true; |
| 753 | } |
| 754 | } |
| 755 | } |
| 756 | } |
| 757 | return false; |
| 758 | } |
| 759 | /* |
| 760 | typedef union compat_sigval { |
| 761 | S32 sival_int; |
no test coverage detected