< prev index next >

src/hotspot/os/windows/os_windows.cpp

Print this page




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);


< prev index next >