Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6277996

Thread in sleep() enters into incorrect status with receiving many interrupt()s

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 6
    • 6
    • hotspot
    • b53
    • x86
    • windows_2000

      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

            collins Gary Collins (Inactive)
            tbaba Tadayuki Baba (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: