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

(se) Selector briefly spins when asynchronously closing a registered channel [win]

    XMLWordPrintable

Details

    • b33
    • 6
    • b28
    • generic, x86, sparc
    • generic, solaris_10, windows_xp, windows_7
    • Verified

    Backports

      Description

        FULL PRODUCT VERSION :
        Mustang b59 fastdebug

        ADDITIONAL OS VERSION INFORMATION :
        XP SP 2

        A DESCRIPTION OF THE PROBLEM :
        I have a select loop, selector is blocked with one key, a socketchannel, interest set = 0. When another thread calls SocketChannel#close, the select wakes up, no keys selected. The loop spins several times until the connection is finally closed.

        Thread state when select first wakes up:

        Thread-0@d8 prio=5, in group "main", status: RUNNING
        close0():-1, SocketDispatcher.java
        preClose():44, SocketDispatcher.java
        implCloseSelectableChannel():630, SocketChannelImpl.java
        implCloseChannel():201, AbstractSelectableChannel.java
        close():97, AbstractInterruptibleChannel.java
        run():33, SelectBlocks.java

        ...

        main@2 prio=5, in group "main", status: RUNNING
        main():44, SelectBlocks.java



        According to my understanding the selector shouldn't wake up at all. And certainly not spin.

        I see a similar phenomenon on Solaris 10 / AMD x64.
        No wakeup with 1.5_05, only one "spurious" wakeup with b59:

        % uname -a
        SunOS sol10sqa 5.10 Generic i86pc i386 i86pc

        Accepted connection = java.nio.channels.SocketChannel[connected local=/10.2.2.22:56420 remote=/10.2.2.22:56421]
        Closing connection
        Closed connection
        Selector: 0/1
        Selector: 0/0


        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Run the attached program. It will open a connection to itself, select on it and close it after one second. It will print a line for each time select wakes up.


        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        JDK 1.5.0_05:

          Accepted connection = java.nio.channels.SocketChannel[connected local=/169.254.69.42:2632 remote=/169.254.69.42:2633]
        Closing connection
          Closed connection
        Selector: 0/0

        ACTUAL -
          Accepted connection = java.nio.channels.SocketChannel[connected local=/169.254.69.42:2684 remote=/169.254.69.42:2685]
        Closing connection
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Selector: 0/1
        Closed connection
        Selector: 0/0


        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        /*
         * Copyright (c) 2005 Matthias Ernst, Hamburg. All rights reserved.
         */
        package test.nio;


        import java.io.IOException;
        import java.net.Socket;
        import java.nio.channels.Selector;
        import java.nio.channels.ServerSocketChannel;
        import java.nio.channels.SocketChannel;

        public class SelectBlocks {
          public static void main(String[] args) throws IOException {
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.socket().bind(null);

            new Socket(serverSocketChannel.socket().getInetAddress(), serverSocketChannel.socket().getLocalPort());
            final SocketChannel connection = serverSocketChannel.accept();

            System.out.println("Accepted connection = " + connection);

            connection.configureBlocking(false);

            final Selector selector = Selector.open();
            connection.register(selector, 0);

            new Thread() {
              public void run() {
                try {
                  Thread.sleep(1000);
                  System.out.println("Closing connection");
                  connection.close();
                  System.out.println("Closed connection");
                  selector.wakeup();
                } catch (Exception e) {
                  e.printStackTrace();
                }
              }
            }.start();

            while(true) {
              selector.select();
              System.out.println("Selector: "+selector.selectedKeys().size()+"/"+selector.keys().size());
              selector.selectedKeys().clear();
            }
          }
        }

        ---------- END SOURCE ----------

        Attachments

          Issue Links

            Activity

              People

                alanb Alan Bateman
                ndcosta Nelson Dcosta (Inactive)
                Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: