3730 static HANDLE handles[MAXIMUM_THREADS_TO_KEEP];
3731 static int handle_count = 0;
3732
3733 static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT;
3734 static CRITICAL_SECTION crit_sect;
3735 static volatile DWORD process_exiting = 0;
3736 int i, j;
3737 DWORD res;
3738 HANDLE hproc, hthr;
3739
3740 // We only attempt to register threads until a process exiting
3741 // thread manages to set the process_exiting flag. Any threads
3742 // that come through here after the process_exiting flag is set
3743 // are unregistered and will be caught in the SuspendThread()
3744 // infinite loop below.
3745 bool registered = false;
3746
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)) {
3749 warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__);
3750 } else if (OrderAccess::load_acquire(&process_exiting) == 0) {
3751 if (what != EPT_THREAD) {
3752 // Atomically set process_exiting before the critical section
3753 // to increase the visibility between racing threads.
3754 Atomic::cmpxchg(GetCurrentThreadId(), &process_exiting, (DWORD)0);
3755 }
3756 EnterCriticalSection(&crit_sect);
3757
3758 if (what == EPT_THREAD && OrderAccess::load_acquire(&process_exiting) == 0) {
3759 // Remove from the array those handles of the threads that have completed exiting.
3760 for (i = 0, j = 0; i < handle_count; ++i) {
3761 res = WaitForSingleObject(handles[i], 0 /* don't wait */);
3762 if (res == WAIT_TIMEOUT) {
3763 handles[j++] = handles[i];
3764 } else {
3765 if (res == WAIT_FAILED) {
3766 warning("WaitForSingleObject failed (%u) in %s: %d\n",
3767 GetLastError(), __FILE__, __LINE__);
3768 }
3769 // Don't keep the handle, if we failed waiting for it.
3770 CloseHandle(handles[i]);
3771 }
3772 }
3773
3774 // If there's no free slot in the array of the kept handles, we'll have to
3775 // wait until at least one thread completes exiting.
3776 if ((handle_count = j) == MAXIMUM_THREADS_TO_KEEP) {
3777 // Raise the priority of the oldest exiting thread to increase its chances
3778 // to complete sooner.
3851 GetLastError(), __FILE__, __LINE__);
3852 // Reset portion_count so we close the remaining
3853 // handles due to this error.
3854 portion_count = handle_count - i;
3855 }
3856 for (j = 0; j < portion_count; ++j) {
3857 CloseHandle(handles[i + j]);
3858 }
3859 if ((i += portion_count) >= handle_count) {
3860 break;
3861 }
3862 start_time = os::javaTimeNanos();
3863 }
3864 handle_count = 0;
3865 }
3866
3867 LeaveCriticalSection(&crit_sect);
3868 }
3869
3870 if (!registered &&
3871 OrderAccess::load_acquire(&process_exiting) != 0 &&
3872 process_exiting != GetCurrentThreadId()) {
3873 // Some other thread is about to call exit(), so we don't let
3874 // the current unregistered thread proceed to exit() or _endthreadex()
3875 while (true) {
3876 SuspendThread(GetCurrentThread());
3877 // Avoid busy-wait loop, if SuspendThread() failed.
3878 Sleep(EXIT_TIMEOUT);
3879 }
3880 }
3881 }
3882
3883 // We are here if either
3884 // - there's no 'race at exit' bug on this OS release;
3885 // - initialization of the critical section failed (unlikely);
3886 // - the current thread has registered itself and left the critical section;
3887 // - the process-exiting thread has raised the flag and left the critical section.
3888 if (what == EPT_THREAD) {
3889 _endthreadex((unsigned)exit_code);
3890 } else if (what == EPT_PROCESS) {
3891 ::exit(exit_code);
|
3730 static HANDLE handles[MAXIMUM_THREADS_TO_KEEP];
3731 static int handle_count = 0;
3732
3733 static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT;
3734 static CRITICAL_SECTION crit_sect;
3735 static volatile DWORD process_exiting = 0;
3736 int i, j;
3737 DWORD res;
3738 HANDLE hproc, hthr;
3739
3740 // We only attempt to register threads until a process exiting
3741 // thread manages to set the process_exiting flag. Any threads
3742 // that come through here after the process_exiting flag is set
3743 // are unregistered and will be caught in the SuspendThread()
3744 // infinite loop below.
3745 bool registered = false;
3746
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)) {
3749 warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__);
3750 } else if (Atomic::load_acquire(&process_exiting) == 0) {
3751 if (what != EPT_THREAD) {
3752 // Atomically set process_exiting before the critical section
3753 // to increase the visibility between racing threads.
3754 Atomic::cmpxchg(GetCurrentThreadId(), &process_exiting, (DWORD)0);
3755 }
3756 EnterCriticalSection(&crit_sect);
3757
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.
3760 for (i = 0, j = 0; i < handle_count; ++i) {
3761 res = WaitForSingleObject(handles[i], 0 /* don't wait */);
3762 if (res == WAIT_TIMEOUT) {
3763 handles[j++] = handles[i];
3764 } else {
3765 if (res == WAIT_FAILED) {
3766 warning("WaitForSingleObject failed (%u) in %s: %d\n",
3767 GetLastError(), __FILE__, __LINE__);
3768 }
3769 // Don't keep the handle, if we failed waiting for it.
3770 CloseHandle(handles[i]);
3771 }
3772 }
3773
3774 // If there's no free slot in the array of the kept handles, we'll have to
3775 // wait until at least one thread completes exiting.
3776 if ((handle_count = j) == MAXIMUM_THREADS_TO_KEEP) {
3777 // Raise the priority of the oldest exiting thread to increase its chances
3778 // to complete sooner.
3851 GetLastError(), __FILE__, __LINE__);
3852 // Reset portion_count so we close the remaining
3853 // handles due to this error.
3854 portion_count = handle_count - i;
3855 }
3856 for (j = 0; j < portion_count; ++j) {
3857 CloseHandle(handles[i + j]);
3858 }
3859 if ((i += portion_count) >= handle_count) {
3860 break;
3861 }
3862 start_time = os::javaTimeNanos();
3863 }
3864 handle_count = 0;
3865 }
3866
3867 LeaveCriticalSection(&crit_sect);
3868 }
3869
3870 if (!registered &&
3871 Atomic::load_acquire(&process_exiting) != 0 &&
3872 process_exiting != GetCurrentThreadId()) {
3873 // Some other thread is about to call exit(), so we don't let
3874 // the current unregistered thread proceed to exit() or _endthreadex()
3875 while (true) {
3876 SuspendThread(GetCurrentThread());
3877 // Avoid busy-wait loop, if SuspendThread() failed.
3878 Sleep(EXIT_TIMEOUT);
3879 }
3880 }
3881 }
3882
3883 // We are here if either
3884 // - there's no 'race at exit' bug on this OS release;
3885 // - initialization of the critical section failed (unlikely);
3886 // - the current thread has registered itself and left the critical section;
3887 // - the process-exiting thread has raised the flag and left the critical section.
3888 if (what == EPT_THREAD) {
3889 _endthreadex((unsigned)exit_code);
3890 } else if (what == EPT_PROCESS) {
3891 ::exit(exit_code);
|