Mercurial > hg > truffle
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 |