src/os/windows/vm/os_windows.cpp

Print this page




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 }