Mercurial > hg > truffle
comparison src/os/windows/vm/os_windows.cpp @ 14649:f6301b007a16
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 | 6c9332549827 |
children | b51e29501f30 |
comparison
equal
deleted
inserted
replaced
14648:4c76be9856fc | 14649:f6301b007a16 |
---|---|
3617 bool os::is_interrupted(Thread* thread, bool clear_interrupted) { | 3617 bool os::is_interrupted(Thread* thread, bool clear_interrupted) { |
3618 assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(), | 3618 assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(), |
3619 "possibility of dangling Thread pointer"); | 3619 "possibility of dangling Thread pointer"); |
3620 | 3620 |
3621 OSThread* osthread = thread->osthread(); | 3621 OSThread* osthread = thread->osthread(); |
3622 bool interrupted = osthread->interrupted(); | |
3623 // There is no synchronization between the setting of the interrupt | 3622 // There is no synchronization between the setting of the interrupt |
3624 // and it being cleared here. It is critical - see 6535709 - that | 3623 // and it being cleared here. It is critical - see 6535709 - that |
3625 // we only clear the interrupt state, and reset the interrupt event, | 3624 // we only clear the interrupt state, and reset the interrupt event, |
3626 // if we are going to report that we were indeed interrupted - else | 3625 // if we are going to report that we were indeed interrupted - else |
3627 // an interrupt can be "lost", leading to spurious wakeups or lost wakeups | 3626 // an interrupt can be "lost", leading to spurious wakeups or lost wakeups |
3628 // depending on the timing | 3627 // depending on the timing. By checking thread interrupt event to see |
3628 // if the thread gets real interrupt thus prevent spurious wakeup. | |
3629 bool interrupted = osthread->interrupted() && (WaitForSingleObject(osthread->interrupt_event(), 0) == WAIT_OBJECT_0); | |
3629 if (interrupted && clear_interrupted) { | 3630 if (interrupted && clear_interrupted) { |
3630 osthread->set_interrupted(false); | 3631 osthread->set_interrupted(false); |
3631 ResetEvent(osthread->interrupt_event()); | 3632 ResetEvent(osthread->interrupt_event()); |
3632 } // Otherwise leave the interrupted state alone | 3633 } // Otherwise leave the interrupted state alone |
3633 | 3634 |