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

(so) Selectors do not handle POLLHUP correctly (lnx)

XMLWordPrintable

    • rc
    • x86
    • linux
    • Verified


      ###@###.### 2001-12-21

      J2SE Version (please include all output from java -version flag):

           1.4 CAP build #88 (also reproducable on build #82)

           % java -version
           java version "1.4.0-rc"
           Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-rc-b88)
           Java HotSpot(TM) Client VM (build 1.4.0-rc-b88, mixed mode)


      Does this problem occur on J2SE 1.3? Yes / No (pick one)

           N.A. its a NIO bug


      Operating System Configuration Information (be specific):

          Redhat Linux 6.2 (Kernel 2.2.16)
          Also reproducable on Redhat Linux 6.1 (2.2.12) running CAP build #82

          Hardware Configuration Information (be specific):
          i586 linux boxes. One with a pentium, one with an AMD K6


      Bug Description:

      Attached a simple non-blocking server program(NonBlockingServer.java)
      using the Selector class. It works fine until a client forcibly
      disconnects. Then the Selector.select() call stops blocking and starts
      immediately returning a zero-length set of SelectionKeys. It is not
      blocking because one of the client channels has closed, but it isn't
      putting the corresponding key into the ready set.

      The server does continue to handle requests from other connected
      clients. The problem is that it is no longer blocking. Instead, the
      select() call returns immediately, so it is effectively converted to a
      very innefficient polling server. Closed channels and their selection
      keys never get cancelled and removed from the selector's set of keys.

      Frist tried to workaround the problem by checking for a zero-length
      return value, and when I find such a ready set going and looping through the
      complete set of registered keys, looking for one that has been
      closed. Unfortunately, that didn't help because none of the channels (or
      their underlying sockets) reports that it is closed.(See attached workaround
      section in the sample code)

      So tried another workaround by checking the return value of read() call.
      If it returns -1, then you know that the client has disconnected,
      and you can close the channel and cancel the key.
      The workaround for the sample code is to change this line:

      client.read(buffer);
      To these:

      int bytesread = client.read(buffer);

      // If read() returns -1, it indicates end-of-stream, which
      // means the client has disconnected, so de-register the
      // selection key and close the channel.
      if (bytesread == -1) {
      key.cancel();
      client.close();
      continue;
      }

      Note, however, that there is still a bug: the select() call is supposed
      to block and return a non-empty Set of selection keys, it should not have
      broken the select() method!

      Need to include a non-blocking server example like this in the 4th edition
      of the book Java in a Nutshell, but not be able to get this bug sorted out
      quickly before the book goes into production!

      Steps to Reproduce (be specific):

      1) Compile and run the program below.
      2) Connect to the server on port 8000 using telnet:

          telnet localhost 8000
         
      3) Disconnect the client. Typically this involves typing the ^] escape
         character and then typing "close" or "quit".

      4) You should see the server start to spew debugging messages indicating
         that the select call has stopped blocking.

            mr Mark Reinhold
            tyao Ting-Yun Ingrid Yao (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: