comparison src/os/windows/vm/os_windows.cpp @ 17716:cdb71841f4bc

6498581: ThreadInterruptTest3 produces wrong output on Windows Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set. Reviewed-by: acorn, kvn Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author minqi
date Wed, 26 Feb 2014 15:20:41 -0800
parents 0e6af9b390af
children 98af1e198e73
comparison
equal deleted inserted replaced
17713:e7cf34c87433 17716:cdb71841f4bc
3631 bool os::is_interrupted(Thread* thread, bool clear_interrupted) { 3631 bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
3632 assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(), 3632 assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(),
3633 "possibility of dangling Thread pointer"); 3633 "possibility of dangling Thread pointer");
3634 3634
3635 OSThread* osthread = thread->osthread(); 3635 OSThread* osthread = thread->osthread();
3636 bool interrupted = osthread->interrupted();
3637 // There is no synchronization between the setting of the interrupt 3636 // There is no synchronization between the setting of the interrupt
3638 // and it being cleared here. It is critical - see 6535709 - that 3637 // and it being cleared here. It is critical - see 6535709 - that
3639 // we only clear the interrupt state, and reset the interrupt event, 3638 // we only clear the interrupt state, and reset the interrupt event,
3640 // if we are going to report that we were indeed interrupted - else 3639 // if we are going to report that we were indeed interrupted - else
3641 // an interrupt can be "lost", leading to spurious wakeups or lost wakeups 3640 // an interrupt can be "lost", leading to spurious wakeups or lost wakeups
3642 // depending on the timing 3641 // depending on the timing. By checking thread interrupt event to see
3642 // if the thread gets real interrupt thus prevent spurious wakeup.
3643 bool interrupted = osthread->interrupted() && (WaitForSingleObject(osthread->interrupt_event(), 0) == WAIT_OBJECT_0);
3643 if (interrupted && clear_interrupted) { 3644 if (interrupted && clear_interrupted) {
3644 osthread->set_interrupted(false); 3645 osthread->set_interrupted(false);
3645 ResetEvent(osthread->interrupt_event()); 3646 ResetEvent(osthread->interrupt_event());
3646 } // Otherwise leave the interrupted state alone 3647 } // Otherwise leave the interrupted state alone
3647 3648