A customer has found out an issue.
When a sleep thread is interrupted by interrupt(), the thread becomes not to
accept interruption and stays sleep on multi-processor system or HyperThreading
machine in Windows.
The attached program interrupts a sleeping thread many times.
The program outputs numbers(integer) when the thread receives
interruption.
During some minutes run, the program enters into sleep status.
In Windosws, the program seems freeze.
In linux, program shows "NG : true" and exit.
REPRODUCE :
(1) Compile the attached test program (InterruptTest.java)
(2) Launch "java InterruptTest"
The program keep showing integers.
--- TEST PROGRAM --->
class InterruptTest {
public static Thread target;
public static void main(String[] args) {
target = Thread.currentThread();
new Interrupter().start();
infinite_sleep();
}
static void infinite_sleep() {
int i = 0;
while (true) {
try {
Thread.sleep(10000000);
System.out.println("NG : " + Thread.currentThread().isInterrupted());
System.exit(255);
} catch (InterruptedException ie) {
System.out.println(++i);
}
}
}
}
class Interrupter extends Thread {
public void run() {
Thread target = InterruptTest.target;
while (true) {
if (!target.isInterrupted()) {
target.interrupt();
}
}
}
}
---------------------
BEHAVIOR :
In Windows, the program freezes as follows.
( Windows/x86, JDK1.4.2_08/Mustang-b31)
---->
C:\>java InterruptTest
.....
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
<== No output
<--------
The message listed below is thread dump.
---- Thread Dump --->
Full thread dump Java HotSpot(TM) Client VM (1.4.2_08-b03 mixed mode):
"Thread-0" prio=5 tid=0x00a44110 nid=0x1310 runnable [2cff000..2cffd8c]
at java.lang.Thread.isInterrupted(Native Method)
at java.lang.Thread.isInterrupted(Thread.java:764)
at Interrupter.run(InterruptTest.java:29)
"Signal Dispatcher" daemon prio=10 tid=0x00a5c950 nid=0x106c waiting on condition [0..0]
"Finalizer" daemon prio=9 tid=0x009fc138 nid=0x1c64 in Object.wait() [2bbf000..2bbfd8c]
at java.lang.Object.wait(Native Method)
- waiting on <0x104f8ff8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:111)
- locked <0x104f8ff8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:127)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
"Reference Handler" daemon prio=10 tid=0x009fadb8 nid=0x121c in Object.wait() [2b7f000..2b7fd8c]
at java.lang.Object.wait(Native Method)
- waiting on <0x104f9060> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:429)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:115)
- locked <0x104f9060> (a java.lang.ref.Reference$Lock)
"main" prio=5 tid=0x00035c28 nid=0xa3c waiting on condition [7f000..7fc38]
at java.lang.Thread.sleep(Native Method)
at InterruptTest.infinite_sleep(InterruptTest.java:14)
at InterruptTest.main(InterruptTest.java:7)
"VM Thread" prio=5 tid=0x00a3b6e8 nid=0x1268 runnable
"VM Periodic Task Thread" prio=10 tid=0x009fe978 nid=0x1a68 waiting on condition
"Suspend Checker Thread" prio=10 tid=0x00a5c008 nid=0x1e68 runnable
<----
The main thread is sleeping status. Thread-0 is executing isInterrupted(), but
the next interrupt() is not executed because isInterrupted() returns true.
REPORT :
The problem is, isInterrupted() returns true, but the target thread keeps sleep.
This situation seems strange.
The cause seems in sleep and interrupt implementation.
The following source code portion are extracted from 1.4.2_0X.
----- hotspo/src/os/win32/vm/os_win32.cpp ---->
....
2060 int os::sleep(Thread* thread, jlong ms, bool interruptable) {
2061 jlong limit = (jlong) MAXDWORD;
.....
2083 if (WaitForMultipleObjects(1, events, FALSE, (DWORD)ms) == WAIT_TIMEOUT) {
2084 result = OS_TIMEOUT;
2085 } else {
2086 osthread->set_interrupted(false);
2087 ResetEvent(osthread->interrupt_event());
2088 result = OS_INTRPT;
2089 }
2217 void os::interrupt(Thread* thread) {
2218 assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(),
2219 "possibility of dangling Thread pointer");
2220
2221 OSThread* osthread = thread->osthread();
2222 osthread->set_interrupted(true);
2223 SetEvent(osthread->interrupt_event());
2224 }
<------
Please assume the following timing when the code is executed.
Sleep Thread Interrupt Thread
--------------------------- ----------------------------------------
2086 osthread->set_interrupted(false);
2222 osthread->set_interrupted(true);
2223 SetEvent(osthread->interrupt_event());
2087 ResetEvent(osthread->interrupt_event());
After the program is excuted in the above sequence,
the status is
- Interrupt Flag : true
- Event : nonsignaled
Because os:sleep() calls WaitForMultibleObject() without checking the flag
set by set_interrupted(), the thread enters into sleep status even though
the interrupt flag is "on".
SUGGESTION :
Customer suggests
- After checking whether interrupt flag status is "on" or "off",
sleep should be done.
Otherwise,
- The line to set/reset interrupt flag and EventObject to signaled/nonsignaled
should be atomic.(critical section?)
###@###.### 2005-05-31 04:18:56 GMT
When a sleep thread is interrupted by interrupt(), the thread becomes not to
accept interruption and stays sleep on multi-processor system or HyperThreading
machine in Windows.
The attached program interrupts a sleeping thread many times.
The program outputs numbers(integer) when the thread receives
interruption.
During some minutes run, the program enters into sleep status.
In Windosws, the program seems freeze.
In linux, program shows "NG : true" and exit.
REPRODUCE :
(1) Compile the attached test program (InterruptTest.java)
(2) Launch "java InterruptTest"
The program keep showing integers.
--- TEST PROGRAM --->
class InterruptTest {
public static Thread target;
public static void main(String[] args) {
target = Thread.currentThread();
new Interrupter().start();
infinite_sleep();
}
static void infinite_sleep() {
int i = 0;
while (true) {
try {
Thread.sleep(10000000);
System.out.println("NG : " + Thread.currentThread().isInterrupted());
System.exit(255);
} catch (InterruptedException ie) {
System.out.println(++i);
}
}
}
}
class Interrupter extends Thread {
public void run() {
Thread target = InterruptTest.target;
while (true) {
if (!target.isInterrupted()) {
target.interrupt();
}
}
}
}
---------------------
BEHAVIOR :
In Windows, the program freezes as follows.
( Windows/x86, JDK1.4.2_08/Mustang-b31)
---->
C:\>java InterruptTest
.....
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
<== No output
<--------
The message listed below is thread dump.
---- Thread Dump --->
Full thread dump Java HotSpot(TM) Client VM (1.4.2_08-b03 mixed mode):
"Thread-0" prio=5 tid=0x00a44110 nid=0x1310 runnable [2cff000..2cffd8c]
at java.lang.Thread.isInterrupted(Native Method)
at java.lang.Thread.isInterrupted(Thread.java:764)
at Interrupter.run(InterruptTest.java:29)
"Signal Dispatcher" daemon prio=10 tid=0x00a5c950 nid=0x106c waiting on condition [0..0]
"Finalizer" daemon prio=9 tid=0x009fc138 nid=0x1c64 in Object.wait() [2bbf000..2bbfd8c]
at java.lang.Object.wait(Native Method)
- waiting on <0x104f8ff8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:111)
- locked <0x104f8ff8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:127)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
"Reference Handler" daemon prio=10 tid=0x009fadb8 nid=0x121c in Object.wait() [2b7f000..2b7fd8c]
at java.lang.Object.wait(Native Method)
- waiting on <0x104f9060> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:429)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:115)
- locked <0x104f9060> (a java.lang.ref.Reference$Lock)
"main" prio=5 tid=0x00035c28 nid=0xa3c waiting on condition [7f000..7fc38]
at java.lang.Thread.sleep(Native Method)
at InterruptTest.infinite_sleep(InterruptTest.java:14)
at InterruptTest.main(InterruptTest.java:7)
"VM Thread" prio=5 tid=0x00a3b6e8 nid=0x1268 runnable
"VM Periodic Task Thread" prio=10 tid=0x009fe978 nid=0x1a68 waiting on condition
"Suspend Checker Thread" prio=10 tid=0x00a5c008 nid=0x1e68 runnable
<----
The main thread is sleeping status. Thread-0 is executing isInterrupted(), but
the next interrupt() is not executed because isInterrupted() returns true.
REPORT :
The problem is, isInterrupted() returns true, but the target thread keeps sleep.
This situation seems strange.
The cause seems in sleep and interrupt implementation.
The following source code portion are extracted from 1.4.2_0X.
----- hotspo/src/os/win32/vm/os_win32.cpp ---->
....
2060 int os::sleep(Thread* thread, jlong ms, bool interruptable) {
2061 jlong limit = (jlong) MAXDWORD;
.....
2083 if (WaitForMultipleObjects(1, events, FALSE, (DWORD)ms) == WAIT_TIMEOUT) {
2084 result = OS_TIMEOUT;
2085 } else {
2086 osthread->set_interrupted(false);
2087 ResetEvent(osthread->interrupt_event());
2088 result = OS_INTRPT;
2089 }
2217 void os::interrupt(Thread* thread) {
2218 assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(),
2219 "possibility of dangling Thread pointer");
2220
2221 OSThread* osthread = thread->osthread();
2222 osthread->set_interrupted(true);
2223 SetEvent(osthread->interrupt_event());
2224 }
<------
Please assume the following timing when the code is executed.
Sleep Thread Interrupt Thread
--------------------------- ----------------------------------------
2086 osthread->set_interrupted(false);
2222 osthread->set_interrupted(true);
2223 SetEvent(osthread->interrupt_event());
2087 ResetEvent(osthread->interrupt_event());
After the program is excuted in the above sequence,
the status is
- Interrupt Flag : true
- Event : nonsignaled
Because os:sleep() calls WaitForMultibleObject() without checking the flag
set by set_interrupted(), the thread enters into sleep status even though
the interrupt flag is "on".
SUGGESTION :
Customer suggests
- After checking whether interrupt flag status is "on" or "off",
sleep should be done.
Otherwise,
- The line to set/reset interrupt flag and EventObject to signaled/nonsignaled
should be atomic.(critical section?)
###@###.### 2005-05-31 04:18:56 GMT