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

nio: Intermittent crash on SocketChannel.register()

XMLWordPrintable

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



      Name: bsC130419 Date: 06/18/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)

      Running a test webserver based on the nio classes, the JVM crashes
      intermittently (every 2-3 minutes under heavy load), on the
      SocketChannel.register() call:

      An unexpected exception has been detected in native code outside the VM.
      Unexpected Signal : EXCEPTION_ACCESS_VIOLATION occurred at PC=0x77FC9E82
      Function=RtlFreeHeap+0x241
      Library=C:\WINNT\System32\ntdll.dll

      Current Java thread:
               at sun.misc.Unsafe.freeMemory(Native Method)
               at sun.misc.AllocatedNativeObject.free(Unknown Source)
               - locked <02A9E970> (a sun.misc.AllocatedNativeObject)
               at sun.nio.ch.PollArrayWrapper.grow(Unknown Source)
               at sun.nio.ch.SelectorImpl.register(Unknown Source)
               - locked <02A9A540> (a sun.nio.ch.SelectorImpl$Lock)
               at sun.nio.ch.SelectorImpl.register(Unknown Source)
               at java.nio.channels.spi.AbstractSelectableChannel.register(Unknown
      Source)
               - locked <02A54830> (a java.lang.Object)
               at WebServer.handleSelectionKey(WebServer2.java:109)
               at WebServer.acceptConnections(WebServer2.java:87)
               at WebServer.<init>(WebServer2.java:44)
               at WebServer.main(WebServer2.java:284)

      Occasionally, the program will rather crash with a Windows dialog box
      saying "java.exe has generated errors and will be closed by Windows".

      The problem has been found both Windows 2000 machines tested, one a 400mhz
      celeron (fresh install), and one an 1100 mhz athlon. Both were patched to
      Service Pack 2.

      The problem seems to occur more frequently if the program sending the HTTP
      requests is executed on a different machine.

      ***************

      Source (note that source has been reformatted so line numbers do not match
      the error message):

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


      public class WebServer {
           int PORT=81;

           boolean verbose=false;


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

           int count=0;

           ByteBuffer writebuffer=ByteBuffer.allocateDirect(2048);


           public WebServer() throws Exception {
               acceptConnections(PORT);
           }


           public static void main(String[] args) {

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


           // Accept connections
           protected void acceptConnections(int port) throws Exception {
               System.out.println("Listening on "+port);

               // Selector for incoming requests
               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);


               do {
                   int keysAdded = acceptSelector.select();
                   if (keysAdded<=0) 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 requests.
                   while (i.hasNext()) {
                       SelectionKey sk = (SelectionKey)i.next();
                       i.remove();
                       handleSelectionKey(sk,acceptSelector);
                   }
               }
               while(true);
           }

           /**
      Handles incoming keys
            */
           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();
                       s.setTcpNoDelay(true);
                       SocketChannel sc=s.getChannel();
                       sc.configureBlocking(false);
                       SelectionKey readKey = sc.register(selector,
                       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();
                   }
               }
           }

           protected void handleWrite(SelectionKey sk) {
               try {

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


           /**
      If there is incoming data, assume that it is a HTTP request
      and send back data
            */
           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();
               }

           }

      protected void writeToSocket(SocketChannel channel) throws Exception {

               count++;
               String s2="<html><body>#"+count+"</body></html>";
               String st = "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<st.length();i++) {
                   writebuffer.put((byte)st.charAt(i));
               }

               writebuffer.rewind();
               int n=channel.write(writebuffer);
               if (n<st.length()) {
                   //Should mark the socket as waiting to be writable
                   //and add unsent data to a buffer.
               }
           }


      }



      (Review ID: 126745)
      ======================================================================
      bill.strathearn@Eng 2001-06-22

            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: