3745 bool registered = false; |
3745 bool registered = false; |
3746 |
3746 |
3747 // The first thread that reached this point, initializes the critical section. |
3747 // The first thread that reached this point, initializes the critical section. |
3748 if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) { |
3748 if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) { |
3749 warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__); |
3749 warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__); |
3750 } else if (OrderAccess::load_acquire(&process_exiting) == 0) { |
3750 } else if (Atomic::load_acquire(&process_exiting) == 0) { |
3751 if (what != EPT_THREAD) { |
3751 if (what != EPT_THREAD) { |
3752 // Atomically set process_exiting before the critical section |
3752 // Atomically set process_exiting before the critical section |
3753 // to increase the visibility between racing threads. |
3753 // to increase the visibility between racing threads. |
3754 Atomic::cmpxchg(GetCurrentThreadId(), &process_exiting, (DWORD)0); |
3754 Atomic::cmpxchg(GetCurrentThreadId(), &process_exiting, (DWORD)0); |
3755 } |
3755 } |
3756 EnterCriticalSection(&crit_sect); |
3756 EnterCriticalSection(&crit_sect); |
3757 |
3757 |
3758 if (what == EPT_THREAD && OrderAccess::load_acquire(&process_exiting) == 0) { |
3758 if (what == EPT_THREAD && Atomic::load_acquire(&process_exiting) == 0) { |
3759 // Remove from the array those handles of the threads that have completed exiting. |
3759 // Remove from the array those handles of the threads that have completed exiting. |
3760 for (i = 0, j = 0; i < handle_count; ++i) { |
3760 for (i = 0, j = 0; i < handle_count; ++i) { |
3761 res = WaitForSingleObject(handles[i], 0 /* don't wait */); |
3761 res = WaitForSingleObject(handles[i], 0 /* don't wait */); |
3762 if (res == WAIT_TIMEOUT) { |
3762 if (res == WAIT_TIMEOUT) { |
3763 handles[j++] = handles[i]; |
3763 handles[j++] = handles[i]; |
3866 |
3866 |
3867 LeaveCriticalSection(&crit_sect); |
3867 LeaveCriticalSection(&crit_sect); |
3868 } |
3868 } |
3869 |
3869 |
3870 if (!registered && |
3870 if (!registered && |
3871 OrderAccess::load_acquire(&process_exiting) != 0 && |
3871 Atomic::load_acquire(&process_exiting) != 0 && |
3872 process_exiting != GetCurrentThreadId()) { |
3872 process_exiting != GetCurrentThreadId()) { |
3873 // Some other thread is about to call exit(), so we don't let |
3873 // Some other thread is about to call exit(), so we don't let |
3874 // the current unregistered thread proceed to exit() or _endthreadex() |
3874 // the current unregistered thread proceed to exit() or _endthreadex() |
3875 while (true) { |
3875 while (true) { |
3876 SuspendThread(GetCurrentThread()); |
3876 SuspendThread(GetCurrentThread()); |