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

(so) Timed read with socket adaptor throws ClosedSelectorException if temporary selector GC'ed.

    XMLWordPrintable

    Details

    • Subcomponent:
    • Introduced In Version:
    • Resolved In Build:
      b31
    • CPU:
      other
    • OS:
      generic
    • Verification:
      Not verified

      Backports

        Description

        OPERATING SYSTEM(S)
        -------------------
        First seen on Windows. Failure is also reported on Linux IA32.

        FULL JDK VERSION
        ----------------
        java version "1.6.0_03"
        Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
        Java HotSpot(TM) Client VM (build 1.6.0_03-b05, mixed mode)

        Also fails on 5.0.

        DESCRIPTION
        -----------
        When a SocketChannel is used as the base for a socket InputStream and read() is called, it's possible for the read() to throw a ClosedSelectorException. The exception is thrown if the read() blocks for a long time and the GC runs (at least once) during the block.
                                                                                 
        If the socket has a non-0 timeout then the read() call gets turned into Selector.poll() in the implementation. If the GC runs and decides that SelectWrapper's phantom reference should be cleaned up then a Cleanup associated with this Seletor Wrapper is going ahead and closing the Temporary Selector associated with the Thread before read could finish.
                                          
        The reason we do not see the exception when timeout is not set is because this temporary selector is not obtained in the first place,it just tries to read into the buffer.
                                                                                 
        The temporary selector getting lost should not get lost before the testcase is done using it.

        RECREATION INSTRUCTIONS
        -----------------------

        Run the attached testcase with a reduced amount of memory (ie, with -Xmx5m or so) for faster recreate.

        Exception stack trace:

        Exception in thread "main" java.nio.channels.ClosedSelectorException
               at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:66)
               at sun.nio.ch.SelectorImpl.selectNow(SelectorImpl.java:88)
               at sun.nio.ch.Util.releaseTemporarySelector(Util.java:135)
               at sun.nio.ch.SocketAdaptor$SocketInputStream.read(SocketAdaptor.java:209)
               at sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:86)
               at java.io.InputStream.read(InputStream.java:85)
               at ClosedSelectorTest.main(ClosedSelectorTest.java:63)

        TESTCASE SOURCE
        ---------------
        import java.io.IOException;
        import java.net.InetSocketAddress;
        import java.net.ServerSocket;
        import java.net.Socket;
        import java.nio.channels.ServerSocketChannel;
        import java.nio.channels.SocketChannel;

        public class ClosedSelectorTest {

            public static void main(String[] args) {
                try {
                    // Create a server socket that will open and accept
                    ServerSocketChannel serverSocketChannel =
                    ServerSocketChannel.open();
                    final ServerSocket serverSocket =
                    serverSocketChannel.socket();
                    serverSocket.bind(null);
                    int localPort = serverSocket.getLocalPort();
                    Thread acceptor = new Thread(new Runnable() {
                                                     public void run() {
                                                         try {
                                                             System.out.println("Waiting on serverSocket.accept()");
                                                             System.out.flush(); Socket socket = serverSocket.accept(); System.out.println("Server socket connected");
                                                             System.out.flush();
                                                         } catch (IOException e) {
                                                             e.printStackTrace();
                                                         }
                                                     }
                                                 });
                    acceptor.start();

                    // Create a thread that just creates data to cause the
                    // GC to run
                    Thread t = new Thread(new Runnable() {
                                              public void run() {
                                                  while (true) {
                                                      byte[] bytes = new byte[100000]; System.gc();
                                                  }
                                              }
                                          });
                    t.start();

                    // Create a client socket that will connect and read
                    System.out.println("Connecting to server socket");
                    System.out.flush();
                    SocketChannel channel = SocketChannel.open(new InetSocketAddress("localhost", localPort));
                    System.out.println("Connected to server socket");

                    System.out.flush();
                    try {
                        System.out.println("Reading from socket input stream");
                        System.out.flush();
                        byte[] buffer = new byte[500];
                        Socket socket = channel.socket();
                        socket.setSoTimeout(1000000); // The timeout must be set
                        // to trigger this bug
                        socket.getInputStream().read(buffer);
                    } finally {
                        try {
                            channel.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

          Attachments

            Issue Links

              Activity

                People

                Assignee:
                sherman Xueming Shen
                Reporter:
                elarsen Erik Larsen (Inactive)
                Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                  Dates

                  Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: