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

(ch) Asynchronous closing and interruption generally broken

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P3 P3
    • None
    • 1.4.0
    • core-libs
    • x86
    • windows_2000



      Name: nt126004 Date: 03/06/2002


      FULL PRODUCT VERSION :
      java version "1.4.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
      Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

      FULL OPERATING SYSTEM VERSION :

      Microsoft Windows 2000 [Version 5.00.2195]

      ADDITIONAL OPERATING SYSTEMS :

      A DESCRIPTION OF THE PROBLEM :
      NOTE: This seems to be a regression bug, since it worked
      correctly in Merlin-beta3 (build 1.4.0-beta3-b84). Since
      1.4RC and now in 1.4.0, it is not working.

      When using a DatagramChannel is it not possible to
      asynchronously interrupt or close it. Accourding to the
      specifications, if interrupt() is called on the channel's
      thread, a java.nio.channels.ClosedByInterruptException
      should be thrown. And if the channel's close() method is
      called a java.nio.channels.AsynchronousCloseException
      should be called. Neither of these work.

      The thread dump of the sample program exhibithing this
      incorrect behaviour clearly shows that the DatagramChannel
      is blocked on a receive, and the main thread is blocked
      trying to kill it:

      Full thread dump Java HotSpot(TM) Client VM (1.4.0-b92
      mixed mode):

      "Channel Thread" prio=5 tid=0x0AAFDA60 nid=0x2328 runnable
      [ae8f000..ae8fdb4]
              at sun.nio.ch.DatagramChannelImpl.receive0(Native
      Method)
              at
      sun.nio.ch.DatagramChannelImpl.receiveIntoNativeBuffer
      (DatagramChanne
      lImpl.java:173)
              at sun.nio.ch.DatagramChannelImpl.receive
      (DatagramChannelImpl.java:159)
              at sun.nio.ch.DatagramChannelImpl.receive
      (DatagramChannelImpl.java:116)
              - locked <02A06D08> (a java.lang.Object)
              at Client$1.run(Client.java:37)

      "Signal Dispatcher" daemon prio=10 tid=0x008E3620
      nid=0x2354 waiting on monitor
      [0..0]

      "Finalizer" daemon prio=9 tid=0x0AA90D60 nid=0x2168 waiting
      on monitor [ad4f000.
      .ad4fdb4]
              at java.lang.Object.wait(Native Method)
              - waiting on <02A80138> (a
      java.lang.ref.ReferenceQueue$Lock)
              at java.lang.ref.ReferenceQueue.remove
      (ReferenceQueue.java:111)
              - locked <02A80138> (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=0x0AA90160
      nid=0x2284 waiting on monitor
      [ad0f000..ad0fdb4]
              at java.lang.Object.wait(Native Method)
              - waiting on <02A801A0> (a
      java.lang.ref.Reference$Lock)
              at java.lang.Object.wait(Object.java:426)
              at java.lang.ref.Reference$ReferenceHandler.run
      (Reference.java:113)
              - locked <02A801A0> (a java.lang.ref.Reference$Lock)

      "main" prio=5 tid=0x00234A10 nid=0x22fc waiting for monitor
      entry [6f000..6fc3c]

              at sun.nio.ch.DatagramChannelImpl.kill
      (DatagramChannelImpl.java:492)
              - waiting to lock <02A06D08> (a java.lang.Object)
              at
      sun.nio.ch.DatagramChannelImpl.implCloseSelectableChannel
      (DatagramCha
      nnelImpl.java:487)
              at
      java.nio.channels.spi.AbstractSelectableChannel.implCloseCha
      nnel(Abst
      ractSelectableChannel.java:202)
              at
      java.nio.channels.spi.AbstractInterruptibleChannel$1.interru
      pt(Abstra
      ctInterruptibleChannel.java:147)
              - locked <02A06CF0> (a java.lang.Object)
              at java.lang.Thread.interrupt(Thread.java:741)
              at Client.<init>(Client.java:60)
              at Client.main(Client.java:71)

      "VM Thread" prio=5 tid=0x0094F460 nid=0x2344 runnable

      "VM Periodic Task Thread" prio=10 tid=0x008E22D0 nid=0x2340
      waiting on monitor
      "Suspend Checker Thread" prio=10 tid=0x008E2C60 nid=0x2360
      runnable

      REGRESSION. Last worked in version 1.4

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      USE JDK 1.4.0

      1. Create a thread that opens a datagram channel and
      receives from it
      2. From another thread attempt to close the channel or
      interrupt the thread
      3. the threads lock: the datagram channel thread is blocked
      on i/o, and the other thread is blocked on trying to kill
      the channel

      Using the provided code, execute Client.java

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      Depending on the closing method the expected results are:

      java.nio.channels.AsynchronousCloseException
              at java.nio.channels.spi.AbstractChannel.end
      (AbstractChannel.java:184)
              at sun.nio.ch.DatagramChannelImpl.receive
      (DatagramChannelImpl.java:140)
              at Client$1.run(Client.java:36)

      -or-

      java.nio.channels.ClosedByInterruptException
              at java.nio.channels.spi.AbstractChannel.end
      (AbstractChannel.java:183)
              at sun.nio.ch.DatagramChannelImpl.receive
      (DatagramChannelImpl.java:140)
              at Client$1.run(Client.java:37)

      Actual Results:
      -no exceptions-

      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      //---- Client.java ---

      import java.nio.*;
      import java.nio.channels.*;
      import java.nio.charset.*;
      import java.net.*;

      public class Client
      {
        DatagramChannel channel;
        Client()
        {
          try
          {
      channel = DatagramChannel.open();
      ByteBuffer buf = ByteBuffer.allocate(1000);
      buf.put("This is a datagram message".getBytes());
      buf.flip();
      final InetSocketAddress address = new InetSocketAddress
                                                        ("225.100.10.101",8099);
              // send the datagram message
      channel.send(buf, address);

              // create a new thread the wait for the responses
      Thread t = new Thread()
      {
      private Charset charset = Charset.forName("US-ASCII");
         private CharsetDecoder decoder = charset.newDecoder();
      ByteBuffer buf2 = ByteBuffer.allocate(1000);

      public void run()
      {
      boolean interruptedOrClosed = false;
                      // keep trying till this flag is set
      while(!interruptedOrClosed)
      {
      try
      {
      buf2.clear();
                            
                           // even if we set the socket timeout, it doesn't work
      // channel.socket().setSoTimeout(2000);
                       
      System.out.println("thread waiting to recieve...");
      channel.receive(buf2);
                           // if a server responds
      System.out.println("waiting thread received something");
      buf2.flip();
      System.out.println(decoder.decode(buf2).toString());
      }
      catch(Exception e)
      {
      System.out.println("Some Exception");
                              // should be AsynchronousClose or ClosedByInterrupt
                              // depending on call made below
      e.printStackTrace();
      interruptedOrClosed = true;
      }
      }
      }
      };

              // start the thread to wait for a response
      t.start();

              // we will sleep and on awakening try to stop the waiting thread
      System.out.println("main thread sleeping for 2s");
      Thread.sleep(2000);

              // either use the close() or interrupt() way, comment out one or the
              // other to see that both work.

      //System.out.println("attempting to close channel");
      //channel.close();

      System.out.println("attempting to interrupt inner thread");
      t.interrupt();
           }
           catch(Exception e)
           {
      e.printStackTrace();
           }
           System.out.println("Main thread complete");
        }

        public static void main (String[] args)
        {
      new Client();
        }

      }

      //--- End of Client.java ---

      ==============================================================================
      // if you want to run the server, here is a quick server that
      // should respond once

      // -- Server.java --
      import java.nio.*;
      import java.nio.channels.*;
      import java.nio.charset.*;
      import java.net.*;

      public class Server
      {
      MulticastSocket socket;
      private Charset charset = Charset.forName("US-ASCII");
      private CharsetDecoder decoder = charset.newDecoder();

      Server()
      {
      try
      {
      InetAddress group = InetAddress.getByName("225.100.10.101");
      socket = new MulticastSocket(8099);
      socket.joinGroup(group);
      byte[] buf = new byte[1000];
      DatagramPacket recv = new DatagramPacket(buf, buf.length);
      socket.receive(recv);
      System.out.println("Received: " + new String(recv.getData
      ()).trim());
      InetAddress sender = recv.getAddress();
      String reply = "This is a reply";
      DatagramPacket send = new DatagramPacket(reply.getBytes(),
      reply.length() ,recv.getAddress(), recv.getPort());
      socket.send(send);
      }
      catch(Exception e)
      {
      e.printStackTrace();
      }

      }

      public static void main (String[] args)
      {
      new Server();
      }

      }
      // -- End of Server.java --
      ---------- END SOURCE ----------

      CUSTOMER WORKAROUND :
      Not use latest version of 1.4, but keep using Merlin-beta3

      Release Regression From : merlin-beta3
      The above release value was the last known release where this
      bug was known to work. Since then there has been a regression.

      (Review ID: 139763)
      ======================================================================

            mr Mark Reinhold
            nthompsosunw Nathanael Thompson (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: