3751 } 3752 3753 // try Windows directory 3754 if ((size = GetWindowsDirectory(path, pathLen)) > 0) { 3755 if (size >= pathLen) { 3756 return NULL; // truncated 3757 } 3758 if (jio_snprintf(path + size, pathLen - size, "\\%s", name) == -1) { 3759 return NULL; // truncated 3760 } 3761 if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) { 3762 return result; 3763 } 3764 } 3765 3766 jio_snprintf(ebuf, ebuflen, 3767 "os::win32::load_windows_dll() cannot load %s from system directories.", name); 3768 return NULL; 3769 } 3770 3771 #define MAX_EXIT_HANDLES PRODUCT_ONLY(32) NOT_PRODUCT(128) 3772 #define EXIT_TIMEOUT PRODUCT_ONLY(1000) NOT_PRODUCT(4000) /* 1 sec in product, 4 sec in debug */ 3773 3774 static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) { 3775 InitializeCriticalSection((CRITICAL_SECTION*)pcrit_sect); 3776 return TRUE; 3777 } 3778 3779 int os::win32::exit_process_or_thread(Ept what, int exit_code) { 3780 // Basic approach: 3781 // - Each exiting thread registers its intent to exit and then does so. 3782 // - A thread trying to terminate the process must wait for all 3783 // threads currently exiting to complete their exit. 3784 3785 if (os::win32::has_exit_bug()) { 3786 // The array holds handles of the threads that have started exiting by calling 3787 // _endthreadex(). 3788 // Should be large enough to avoid blocking the exiting thread due to lack of 3789 // a free slot. 3790 static HANDLE handles[MAX_EXIT_HANDLES]; 3791 static int handle_count = 0; 3792 3793 static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT; 3794 static CRITICAL_SECTION crit_sect; 3795 int i, j; 3796 DWORD res; 3797 HANDLE hproc, hthr; 3798 3799 // The first thread that reached this point, initializes the critical section. 3800 if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) { 3801 warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__); 3802 } else { 3803 EnterCriticalSection(&crit_sect); 3804 3805 if (what == EPT_THREAD) { 3806 // Remove from the array those handles of the threads that have completed exiting. 3807 for (i = 0, j = 0; i < handle_count; ++i) { 3808 res = WaitForSingleObject(handles[i], 0 /* don't wait */); 3809 if (res == WAIT_TIMEOUT) { 3810 handles[j++] = handles[i]; 3811 } else { 3812 if (res != WAIT_OBJECT_0) { 3813 warning("WaitForSingleObject failed in %s: %d\n", __FILE__, __LINE__); 3814 // Don't keep the handle, if we failed waiting for it. 3815 } 3816 CloseHandle(handles[i]); 3817 } 3818 } 3819 3820 // If there's no free slot in the array of the kept handles, we'll have to 3821 // wait until at least one thread completes exiting. 3822 if ((handle_count = j) == MAX_EXIT_HANDLES) { 3823 // Raise the priority of the oldest exiting thread to increase its chances 3824 // to complete sooner. 3825 SetThreadPriority(handles[0], THREAD_PRIORITY_ABOVE_NORMAL); 3826 res = WaitForMultipleObjects(MAX_EXIT_HANDLES, handles, FALSE, EXIT_TIMEOUT); 3827 if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAX_EXIT_HANDLES)) { 3828 i = (res - WAIT_OBJECT_0); 3829 handle_count = MAX_EXIT_HANDLES - 1; 3830 for (; i < handle_count; ++i) { 3831 handles[i] = handles[i + 1]; 3832 } 3833 } else { 3834 warning("WaitForMultipleObjects %s in %s: %d\n", 3835 (res == WAIT_FAILED ? "failed" : "timed out"), __FILE__, __LINE__); 3836 // Don't keep handles, if we failed waiting for them. 3837 for (i = 0; i < MAX_EXIT_HANDLES; ++i) { 3838 CloseHandle(handles[i]); 3839 } 3840 handle_count = 0; 3841 } 3842 } 3843 3844 // Store a duplicate of the current thread handle in the array of handles. 3845 hproc = GetCurrentProcess(); 3846 hthr = GetCurrentThread(); 3847 if (!DuplicateHandle(hproc, hthr, hproc, &handles[handle_count], 3848 0, FALSE, DUPLICATE_SAME_ACCESS)) { 3849 warning("DuplicateHandle failed in %s: %d\n", __FILE__, __LINE__); 3850 } else { 3851 ++handle_count; 3852 } 3853 3854 // The current exiting thread has stored its handle in the array, and now 3855 // should leave the critical section before calling _endthreadex(). 3856 3857 } else { // what != EPT_THREAD 3858 if (handle_count > 0) { 3859 // Before ending the process, make sure all the threads that had called 3860 // _endthreadex() completed. 3861 3862 // Set the priority level of the current thread to the same value as 3863 // the priority level of exiting threads. 3864 // This is to ensure it will be given a fair chance to execute if 3865 // the timeout expires. 3866 hthr = GetCurrentThread(); 3867 SetThreadPriority(hthr, THREAD_PRIORITY_ABOVE_NORMAL); 3868 for (i = 0; i < handle_count; ++i) { 3869 SetThreadPriority(handles[i], THREAD_PRIORITY_ABOVE_NORMAL); 3870 } 3871 res = WaitForMultipleObjects(handle_count, handles, TRUE, EXIT_TIMEOUT); 3872 if (res < WAIT_OBJECT_0 || res >= (WAIT_OBJECT_0 + MAX_EXIT_HANDLES)) { 3873 warning("WaitForMultipleObjects %s in %s: %d\n", 3874 (res == WAIT_FAILED ? "failed" : "timed out"), __FILE__, __LINE__); 3875 } 3876 for (i = 0; i < handle_count; ++i) { 3877 CloseHandle(handles[i]); 3878 } 3879 handle_count = 0; 3880 } 3881 3882 // End the process, not leaving critical section. 3883 // This makes sure no other thread executes exit-related code at the same 3884 // time, thus a race is avoided. 3885 if (what == EPT_PROCESS) { 3886 ::exit(exit_code); 3887 } else { 3888 _exit(exit_code); 3889 } 3890 } 3891 3892 LeaveCriticalSection(&crit_sect); 3893 } 3894 } 3895 3896 // We are here if either 3897 // - there's no 'race at exit' bug on this OS release; 3898 // - initialization of the critical section failed (unlikely); 3899 // - the current thread has stored its handle and left the critical section. 3900 if (what == EPT_THREAD) { 3901 _endthreadex((unsigned)exit_code); 3902 } else if (what == EPT_PROCESS) { 3903 ::exit(exit_code); 3904 } else { 3905 _exit(exit_code); 3906 } 3907 3908 // Should not reach here 3909 return exit_code; 3910 } 3911 3912 #undef MAX_EXIT_HANDLES 3913 #undef EXIT_TIMEOUT 3914 3915 void os::win32::setmode_streams() { 3916 _setmode(_fileno(stdin), _O_BINARY); 3917 _setmode(_fileno(stdout), _O_BINARY); 3918 _setmode(_fileno(stderr), _O_BINARY); 3919 } 3920 3921 3922 bool os::is_debugger_attached() { 3923 return IsDebuggerPresent() ? true : false; 3924 } 3925 3926 3927 void os::wait_for_keypress_at_exit(void) { 3928 if (PauseAtExit) { 3929 fprintf(stderr, "Press any key to continue...\n"); 3930 fgetc(stdin); 3931 } 3932 } | 3751 } 3752 3753 // try Windows directory 3754 if ((size = GetWindowsDirectory(path, pathLen)) > 0) { 3755 if (size >= pathLen) { 3756 return NULL; // truncated 3757 } 3758 if (jio_snprintf(path + size, pathLen - size, "\\%s", name) == -1) { 3759 return NULL; // truncated 3760 } 3761 if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) { 3762 return result; 3763 } 3764 } 3765 3766 jio_snprintf(ebuf, ebuflen, 3767 "os::win32::load_windows_dll() cannot load %s from system directories.", name); 3768 return NULL; 3769 } 3770 3771 #define EXIT_TIMEOUT PRODUCT_ONLY(1000) NOT_PRODUCT(4000) /* 1 sec in product, 4 sec in debug */ 3772 3773 static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) { 3774 InitializeCriticalSection((CRITICAL_SECTION*)pcrit_sect); 3775 return TRUE; 3776 } 3777 3778 int os::win32::exit_process_or_thread(Ept what, int exit_code) { 3779 // Basic approach: 3780 // - Each exiting thread registers its intent to exit and then does so. 3781 // - A thread trying to terminate the process must wait for all 3782 // threads currently exiting to complete their exit. 3783 3784 if (os::win32::has_exit_bug()) { 3785 // The array holds handles of the threads that have started exiting by calling 3786 // _endthreadex(). 3787 // Should be large enough to avoid blocking the exiting thread due to lack of 3788 // a free slot. 3789 static HANDLE handles[MAXIMUM_WAIT_OBJECTS]; 3790 static int handle_count = 0; 3791 3792 static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT; 3793 static CRITICAL_SECTION crit_sect; 3794 int i, j; 3795 DWORD res; 3796 HANDLE hproc, hthr; 3797 3798 // 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 warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__); 3801 } else { 3802 EnterCriticalSection(&crit_sect); 3803 3804 if (what == EPT_THREAD) { 3805 // Remove from the array those handles of the threads that have completed exiting. 3806 for (i = 0, j = 0; i < handle_count; ++i) { 3807 res = WaitForSingleObject(handles[i], 0 /* don't wait */); 3808 if (res == WAIT_TIMEOUT) { 3809 handles[j++] = handles[i]; 3810 } else { 3811 if (res == WAIT_FAILED) { 3812 warning("WaitForSingleObject failed (%u) in %s: %d\n", 3813 GetLastError(), __FILE__, __LINE__); 3814 } 3815 // Don't keep the handle, if we failed waiting for it. 3816 CloseHandle(handles[i]); 3817 } 3818 } 3819 3820 // If there's no free slot in the array of the kept handles, we'll have to 3821 // wait until at least one thread completes exiting. 3822 if ((handle_count = j) == MAXIMUM_WAIT_OBJECTS) { 3823 // Raise the priority of the oldest exiting thread to increase its chances 3824 // to complete sooner. 3825 SetThreadPriority(handles[0], THREAD_PRIORITY_ABOVE_NORMAL); 3826 res = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, handles, FALSE, EXIT_TIMEOUT); 3827 if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)) { 3828 i = (res - WAIT_OBJECT_0); 3829 handle_count = MAXIMUM_WAIT_OBJECTS - 1; 3830 for (; i < handle_count; ++i) { 3831 handles[i] = handles[i + 1]; 3832 } 3833 } else { 3834 warning("WaitForMultipleObjects %s (%u) in %s: %d\n", 3835 (res == WAIT_FAILED ? "failed" : "timed out"), 3836 GetLastError(), __FILE__, __LINE__); 3837 // Don't keep handles, if we failed waiting for them. 3838 for (i = 0; i < MAXIMUM_WAIT_OBJECTS; ++i) { 3839 CloseHandle(handles[i]); 3840 } 3841 handle_count = 0; 3842 } 3843 } 3844 3845 // Store a duplicate of the current thread handle in the array of handles. 3846 hproc = GetCurrentProcess(); 3847 hthr = GetCurrentThread(); 3848 if (!DuplicateHandle(hproc, hthr, hproc, &handles[handle_count], 3849 0, FALSE, DUPLICATE_SAME_ACCESS)) { 3850 warning("DuplicateHandle failed (%u) in %s: %d\n", 3851 GetLastError(), __FILE__, __LINE__); 3852 } else { 3853 ++handle_count; 3854 } 3855 3856 // The current exiting thread has stored its handle in the array, and now 3857 // should leave the critical section before calling _endthreadex(). 3858 3859 } else { // what != EPT_THREAD 3860 if (handle_count > 0) { 3861 // Before ending the process, make sure all the threads that had called 3862 // _endthreadex() completed. 3863 3864 // Set the priority level of the current thread to the same value as 3865 // the priority level of exiting threads. 3866 // This is to ensure it will be given a fair chance to execute if 3867 // the timeout expires. 3868 hthr = GetCurrentThread(); 3869 SetThreadPriority(hthr, THREAD_PRIORITY_ABOVE_NORMAL); 3870 for (i = 0; i < handle_count; ++i) { 3871 SetThreadPriority(handles[i], THREAD_PRIORITY_ABOVE_NORMAL); 3872 } 3873 res = WaitForMultipleObjects(handle_count, handles, TRUE, EXIT_TIMEOUT); 3874 if (res == WAIT_FAILED || res == WAIT_TIMEOUT) { 3875 warning("WaitForMultipleObjects %s (%u) in %s: %d\n", 3876 (res == WAIT_FAILED ? "failed" : "timed out"), 3877 GetLastError(), __FILE__, __LINE__); 3878 } 3879 for (i = 0; i < handle_count; ++i) { 3880 CloseHandle(handles[i]); 3881 } 3882 handle_count = 0; 3883 } 3884 3885 // End the process, not leaving critical section. 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 } 3894 3895 LeaveCriticalSection(&crit_sect); 3896 } 3897 } 3898 3899 // We are here if either 3900 // - there's no 'race at exit' bug on this OS release; 3901 // - initialization of the critical section failed (unlikely); 3902 // - the current thread has stored its handle and left the critical section. 3903 if (what == EPT_THREAD) { 3904 _endthreadex((unsigned)exit_code); 3905 } else if (what == EPT_PROCESS) { 3906 ::exit(exit_code); 3907 } else { 3908 _exit(exit_code); 3909 } 3910 3911 // Should not reach here 3912 return exit_code; 3913 } 3914 3915 #undef EXIT_TIMEOUT 3916 3917 void os::win32::setmode_streams() { 3918 _setmode(_fileno(stdin), _O_BINARY); 3919 _setmode(_fileno(stdout), _O_BINARY); 3920 _setmode(_fileno(stderr), _O_BINARY); 3921 } 3922 3923 3924 bool os::is_debugger_attached() { 3925 return IsDebuggerPresent() ? true : false; 3926 } 3927 3928 3929 void os::wait_for_keypress_at_exit(void) { 3930 if (PauseAtExit) { 3931 fprintf(stderr, "Press any key to continue...\n"); 3932 fgetc(stdin); 3933 } 3934 } |