< prev index next >

src/hotspot/share/runtime/thread.cpp

Print this page

        

*** 1677,1725 **** // interrupt support void JavaThread::interrupt() { debug_only(check_for_dangling_thread_pointer(this);) ! if (!osthread()->interrupted()) { osthread()->set_interrupted(true); - // More than one thread can get here with the same value of osthread, - // resulting in multiple notifications. We do, however, want the store - // to interrupted() to be visible to other threads before we execute unpark(). - OrderAccess::fence(); ! // For JavaThread::sleep. Historically we only unpark if changing to the interrupted ! // state, in contrast to the other events below. Not clear exactly why. _SleepEvent->unpark(); - } ! // For JSR166. Unpark even if interrupt status already was set. parker()->unpark(); // For ObjectMonitor and JvmtiRawMonitor _ParkEvent->unpark(); } bool JavaThread::is_interrupted(bool clear_interrupted) { debug_only(check_for_dangling_thread_pointer(this);) ! bool interrupted = osthread()->interrupted(); // NOTE that since there is no "lock" around the interrupt and // is_interrupted operations, there is the possibility that the ! // interrupted flag (in osThread) will be "false" but that the // low-level events will be in the signaled state. This is // intentional. The effect of this is that Object.wait() and // LockSupport.park() will appear to have a spurious wakeup, which // is allowed and not harmful, and the possibility is so rare that // it is not worth the added complexity to add yet another lock. // For the sleep event an explicit reset is performed on entry // to JavaThread::sleep, so there is no early return. It has also been // recommended not to put the interrupted flag into the "event" // structure because it hides the issue. if (interrupted && clear_interrupted) { osthread()->set_interrupted(false); - // consider thread->_SleepEvent->reset() ... optional optimization } return interrupted; } --- 1677,1722 ---- // interrupt support void JavaThread::interrupt() { debug_only(check_for_dangling_thread_pointer(this);) ! // For Windows _interrupt_event osthread()->set_interrupted(true); ! // For Thread.sleep _SleepEvent->unpark(); ! // For JSR166 LockSupport.park parker()->unpark(); // For ObjectMonitor and JvmtiRawMonitor _ParkEvent->unpark(); } bool JavaThread::is_interrupted(bool clear_interrupted) { debug_only(check_for_dangling_thread_pointer(this);) ! bool interrupted = java_lang_Thread::interrupted(threadObj()); // NOTE that since there is no "lock" around the interrupt and // is_interrupted operations, there is the possibility that the ! // interrupted flag will be "false" but that the // low-level events will be in the signaled state. This is // intentional. The effect of this is that Object.wait() and // LockSupport.park() will appear to have a spurious wakeup, which // is allowed and not harmful, and the possibility is so rare that // it is not worth the added complexity to add yet another lock. // For the sleep event an explicit reset is performed on entry // to JavaThread::sleep, so there is no early return. It has also been // recommended not to put the interrupted flag into the "event" // structure because it hides the issue. + // Also, because there is no lock, we must only clear the interrupt + // state if we are going to report that we were interrupted; otherwise + // an interrupt that happens just after we read the field would be lost. if (interrupted && clear_interrupted) { + java_lang_Thread::set_interrupted(threadObj(), false); osthread()->set_interrupted(false); } return interrupted; }
*** 2369,2378 **** --- 2366,2376 ---- } } // Interrupt thread so it will wake up from a potential wait()/sleep()/park() + java_lang_Thread::set_interrupted(threadObj(), true); this->interrupt(); } // External suspension mechanism. //
< prev index next >