426 thread->set_lgrp_id(lgrp_id); |
426 thread->set_lgrp_id(lgrp_id); |
427 } |
427 } |
428 } |
428 } |
429 |
429 |
430 // Diagnostic code to investigate JDK-6573254 |
430 // Diagnostic code to investigate JDK-6573254 |
431 int res = 50115; // non-java thread |
431 int res = 30115; // non-java thread |
432 if (thread->is_Java_thread()) { |
432 if (thread->is_Java_thread()) { |
433 res = 40115; // java thread |
433 res = 20115; // java thread |
434 } |
434 } |
435 |
435 |
436 // Install a win32 structured exception handler around every thread created |
436 // Install a win32 structured exception handler around every thread created |
437 // by VM, so VM can generate error dump when an exception occurred in non- |
437 // by VM, so VM can generate error dump when an exception occurred in non- |
438 // Java thread (e.g. VM thread). |
438 // Java thread (e.g. VM thread). |
3789 static HANDLE handles[MAXIMUM_WAIT_OBJECTS]; |
3789 static HANDLE handles[MAXIMUM_WAIT_OBJECTS]; |
3790 static int handle_count = 0; |
3790 static int handle_count = 0; |
3791 |
3791 |
3792 static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT; |
3792 static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT; |
3793 static CRITICAL_SECTION crit_sect; |
3793 static CRITICAL_SECTION crit_sect; |
|
3794 static volatile jint process_exiting = 0; |
3794 int i, j; |
3795 int i, j; |
3795 DWORD res; |
3796 DWORD res; |
3796 HANDLE hproc, hthr; |
3797 HANDLE hproc, hthr; |
3797 |
3798 |
3798 // The first thread that reached this point, initializes the critical section. |
3799 // The first thread that reached this point, initializes the critical section. |
3799 if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) { |
3800 if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) { |
3800 warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__); |
3801 warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__); |
3801 } else { |
3802 } else if (OrderAccess::load_acquire(&process_exiting) == 0) { |
3802 EnterCriticalSection(&crit_sect); |
3803 EnterCriticalSection(&crit_sect); |
3803 |
3804 |
3804 if (what == EPT_THREAD) { |
3805 if (what == EPT_THREAD && OrderAccess::load_acquire(&process_exiting) == 0) { |
3805 // Remove from the array those handles of the threads that have completed exiting. |
3806 // Remove from the array those handles of the threads that have completed exiting. |
3806 for (i = 0, j = 0; i < handle_count; ++i) { |
3807 for (i = 0, j = 0; i < handle_count; ++i) { |
3807 res = WaitForSingleObject(handles[i], 0 /* don't wait */); |
3808 res = WaitForSingleObject(handles[i], 0 /* don't wait */); |
3808 if (res == WAIT_TIMEOUT) { |
3809 if (res == WAIT_TIMEOUT) { |
3809 handles[j++] = handles[i]; |
3810 handles[j++] = handles[i]; |
3854 } |
3855 } |
3855 |
3856 |
3856 // The current exiting thread has stored its handle in the array, and now |
3857 // The current exiting thread has stored its handle in the array, and now |
3857 // should leave the critical section before calling _endthreadex(). |
3858 // should leave the critical section before calling _endthreadex(). |
3858 |
3859 |
3859 } else { // what != EPT_THREAD |
3860 } else if (what != EPT_THREAD) { |
3860 if (handle_count > 0) { |
3861 if (handle_count > 0) { |
3861 // Before ending the process, make sure all the threads that had called |
3862 // Before ending the process, make sure all the threads that had called |
3862 // _endthreadex() completed. |
3863 // _endthreadex() completed. |
3863 |
3864 |
3864 // Set the priority level of the current thread to the same value as |
3865 // Set the priority level of the current thread to the same value as |
3880 CloseHandle(handles[i]); |
3881 CloseHandle(handles[i]); |
3881 } |
3882 } |
3882 handle_count = 0; |
3883 handle_count = 0; |
3883 } |
3884 } |
3884 |
3885 |
3885 // End the process, not leaving critical section. |
3886 OrderAccess::release_store(&process_exiting, 1); |
3886 // This makes sure no other thread executes exit-related code at the same |
|
3887 // time, thus a race is avoided. |
|
3888 if (what == EPT_PROCESS) { |
|
3889 ::exit(exit_code); |
|
3890 } else { |
|
3891 _exit(exit_code); |
|
3892 } |
|
3893 } |
3887 } |
3894 |
3888 |
3895 LeaveCriticalSection(&crit_sect); |
3889 LeaveCriticalSection(&crit_sect); |
|
3890 } |
|
3891 |
|
3892 if (what == EPT_THREAD) { |
|
3893 while (OrderAccess::load_acquire(&process_exiting) != 0) { |
|
3894 // Some other thread is about to call exit(), so we |
|
3895 // don't let the current thread proceed to _endthreadex() |
|
3896 SuspendThread(GetCurrentThread()); |
|
3897 // Avoid busy-wait loop, if SuspendThread() failed. |
|
3898 Sleep(EXIT_TIMEOUT); |
|
3899 } |
3896 } |
3900 } |
3897 } |
3901 } |
3898 |
3902 |
3899 // We are here if either |
3903 // We are here if either |
3900 // - there's no 'race at exit' bug on this OS release; |
3904 // - there's no 'race at exit' bug on this OS release; |
3901 // - initialization of the critical section failed (unlikely); |
3905 // - initialization of the critical section failed (unlikely); |
3902 // - the current thread has stored its handle and left the critical section. |
3906 // - the current thread has stored its handle and left the critical section; |
|
3907 // - the process-exiting thread has raised the flag and left the critical section. |
3903 if (what == EPT_THREAD) { |
3908 if (what == EPT_THREAD) { |
3904 _endthreadex((unsigned)exit_code); |
3909 _endthreadex((unsigned)exit_code); |
3905 } else if (what == EPT_PROCESS) { |
3910 } else if (what == EPT_PROCESS) { |
3906 ::exit(exit_code); |
3911 ::exit(exit_code); |
3907 } else { |
3912 } else { |