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

(so) Selector.selectNow() fails if no ServerSocketChannel is registered

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.4.0
    • 1.4.0
    • core-libs
    • beta2
    • x86
    • windows_2000
    • Verified



      Name: bsC130419 Date: 06/21/2001


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

      In an attempt to write a small webserver test with two threads, one waiting on
      SelectionKey.OP_ACCEPT and one waiting on SelectionKey.OP_READ and
      SelectionKey.OP_WRITE:

      Selector.selectNow() throws an exception if no ServerSocketChannel
      has been registered

      readSelector err: java.io.IOException: The parameter is incorrect
      java.io.IOException: The parameter is incorrect
              at sun.nio.ch.PollArrayWrapper.poll0(Native Method)
              at sun.nio.ch.PollArrayWrapper.poll(Unknown Source)
              at sun.nio.ch.SelectorImpl.doSelect(Unknown Source)
              at sun.nio.ch.SelectorImpl.selectNow(Unknown Source)
              at WebServer4.run(WebServer4.java:153)

      It makes no difference if selectNow is only called after a normal SocketChannel
      is registered. The problem is not present in select() or select(<timeout>)

      ********** Source: ***********

      import java.io.*;
      import java.nio.*;
      import java.nio.channels.*;
      import java.nio.channels.spi.*;
      import java.net.*;
      import java.util.*;

      public class WebServer4 extends Thread {
          private static final int PORT = 8900;

          protected boolean verbose=false;

          protected int count=0;

          Selector readSelector;

          protected ByteBuffer readbuffer=ByteBuffer.allocateDirect(1024);
          protected byte readbytes[]=new byte[1024];
          protected ByteBuffer writebuffer=ByteBuffer.allocateDirect(2048);

          /**
      Constructor
           */
          public WebServer4() throws Exception {
              acceptConnections(PORT);
          }

          /**
      Here it waits for the accept connections
           */
          private void acceptConnections(int port) throws Exception {
              System.out.println("Listening on "+port);

              readSelector= SelectorProvider.provider().openSelector();
              Selector acceptSelector = SelectorProvider.provider().openSelector();

              // Create a new server socket and set to non blocking mode
              ServerSocketChannel ssc = ServerSocketChannel.open();
              ssc.configureBlocking(false);

              // Bind the server socket to the local host and port
              InetAddress lh = InetAddress.getLocalHost();
              InetSocketAddress isa = new InetSocketAddress(lh, port);
              ssc.socket().bind(isa);

              SelectionKey acceptKey = ssc.register(acceptSelector,
              SelectionKey.OP_ACCEPT);


              //This is the workaround!
              /*
              ServerSocketChannel ssc2 = ServerSocketChannel.open();
              ssc2.configureBlocking(false);
              SelectionKey dummyKey = ssc2.register(readSelector,
              SelectionKey.OP_ACCEPT);
              */

              start();

              //Loop waiting for accept
              do {
                  int keysAdded = acceptSelector.selectNow();
                  if (keysAdded<=0) {

                      try {
                          Thread.currentThread().sleep(10);
                      }
                      catch(Exception e) {
                      }

                      continue;
                  }
                  // Someone is ready for I/O, get the ready keys
                  Set readyKeys = acceptSelector.selectedKeys();
                  Iterator i = readyKeys.iterator();

                  // Walk through the ready keys collection and process date requests.
                  while (i.hasNext()) {
                      SelectionKey sk = (SelectionKey)i.next();
                      i.remove();
                      handleSelectionKey(sk,acceptSelector);
                  }

              }
              while(true);
          }

          /**
      Handles selections coming from both the acceptselector and the readselector
           */
          protected void handleSelectionKey(SelectionKey sk,Selector selector) {
              try {

                  if (sk.isAcceptable()) {
                      ServerSocketChannel channel =
                      (ServerSocketChannel)sk.channel();
                      if (verbose)
                          System.out.println("Accept");

                      Socket s = channel.accept();
                      SocketChannel sc=s.getChannel();
                      sc.configureBlocking(false);
                      SelectionKey readKey = sc.register(readSelector,
                      SelectionKey.OP_READ|SelectionKey.OP_WRITE);
                  }

                  if (sk.isReadable()) {
                      if (verbose)
                          System.out.println("Read!");
                      handleRead(sk);
                  }
                  if (sk.isWritable()) {
                      if (verbose)
                          System.out.println("Write!");
                      handleWrite(sk);
                  }
                  if (sk.readyOps()==0) {
                      System.out.println("No ready ops!!");
                  }
              }
              catch(Exception e) {
                  if (e instanceof CancelledKeyException) {
                  }
                  else {
                      System.out.println("handleSelectionKey err: ");
                      e.printStackTrace();
                  }
              }
          }



          // Entry point.
          public static void main(String[] args) {

              try {
                  WebServer4 nbt = new WebServer4();
              } catch(Exception e) {
                  e.printStackTrace();
              }
          }


          /**
      The other thread waits here for read and write messages

           */
          public void run() {
              try {

                  //Loop waiting for read and write
                  do {
                      int keysAdded = readSelector.selectNow();
                      //int keysAdded = readSelector.select(10);

                      if (keysAdded<=0) {

                          try {
                              Thread.currentThread().sleep(10);
                          }
                          catch(Exception e) {
                          }

                          continue;
                      }
                      // Someone is ready for I/O, get the ready keys
                      Set readyKeys = readSelector.selectedKeys();
                      Iterator i = readyKeys.iterator();

                      // Walk through the ready keys collection and process date
      requests.
                      while (i.hasNext()) {
                          SelectionKey sk = (SelectionKey)i.next();
                          i.remove();
                          handleSelectionKey(sk,readSelector);
                      }

                  }
                  while(true);
              }
              catch(Exception e) {
                  System.out.println("readSelector err: "+e);
                  e.printStackTrace();
              }
          }



          protected void handleWrite(SelectionKey sk) {
              try {

                  SocketChannel channel =
                  (SocketChannel)sk.channel();
              }
              catch(Exception e) {
                  System.out.println("handleWrite err: ");
                  e.printStackTrace();
              }
          }


          protected void handleRead(SelectionKey sk) {
              try {
                  SocketChannel channel =
                  (SocketChannel)sk.channel();

                  boolean read=false;
                  do {
                      readbuffer.rewind();
                      int n=channel.read(readbuffer);
                      if (n<=0) break;
                      read=true;

                      readbuffer.rewind();
                      readbuffer.get(readbytes);
                      String s=new String(readbytes,0,n);
                      if (verbose)
                          System.out.println("Got "+n+": "+s);
                  }
                  while(true);

                  writeToSocket(channel);
                  channel.close();

              }
              catch(Exception e) {
                  // System.out.println("handleRead err: ");
                  // e.printStackTrace();
              }

          }


          /**
      Writes to a socket channel
           */
          protected void writeToSocket(SocketChannel channel) throws Exception {

              count++;

              String s2="<html><body>#"+count+"</body></html>";

              String send = "HTTP/1.0 200 OK\n" +
              "Allow: GET, POST\n"+
              "MIME-Version: 1.0\n"+
              "Content-Type: text/html\n"+
              "Content-length: "+s2.length()+"\n\n"+
              s2;
              writebuffer.rewind();
              for (int i=0;i<send.length();i++) {
                  writebuffer.put((byte)send.charAt(i));
              }

              writebuffer.rewind();
              long time=System.currentTimeMillis();
              int n=channel.write(writebuffer);
              long time2=System.currentTimeMillis();
              if (verbose)
                  System.out.println("String: "+send.length()+", written: "+n);
              if (verbose)
                  System.out.println("Time taken: "+(time2-time));
              if (n<send.length()) {
                  //mark the socket as waiting to be writable
                  //Should really add unsent data to a buffer.
              }
          }

      }
      (Review ID: 126936)
      ======================================================================

            mmcclosksunw Michael Mccloskey (Inactive)
            bstrathesunw Bill Strathearn (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: