You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ml...@apache.org on 2006/06/02 12:24:06 UTC

svn commit: r411114 - in /incubator/harmony/enhanced/classlib/trunk/modules/nio/src: main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java test/java/org/apache/harmony/tests/java/nio/channels/SocketChannelTest.java

Author: mloenko
Date: Fri Jun  2 03:24:01 2006
New Revision: 411114

URL: http://svn.apache.org/viewvc?rev=411114&view=rev
Log:
fixes for HARMONY-549
[classlib][nio-channels]java.nio.channels.SocketChannel.read/write mis-acts in some condition

Modified:
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java
    incubator/harmony/enhanced/classlib/trunk/modules/nio/src/test/java/org/apache/harmony/tests/java/nio/channels/SocketChannelTest.java

Modified: incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java?rev=411114&r1=411113&r2=411114&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java Fri Jun  2 03:24:01 2006
@@ -260,10 +260,9 @@
 
         // connect result
         int result = EOF;
-        boolean success = false;
+        boolean finished = false;
 
-        try {
-            begin();
+        try {           
             if (!isBound) {
                 // bind
                 networkSystem.bind2(fd, 0, true, InetAddress
@@ -274,6 +273,7 @@
             localAddress = networkSystem.getSocketLocalAddress(fd, false);
 
             if (isBlocking()) {
+                begin();
                 result = networkSystem.connect(fd, trafficClass,
                         inetSocketAddress.getAddress(), inetSocketAddress
                                 .getPort());
@@ -283,32 +283,35 @@
                         inetSocketAddress.getAddress(), inetSocketAddress
                                 .getPort(), HY_SOCK_STEP_START, connectContext);
             }
-
-            success = (CONNECT_SUCCESS == result);
-
-            isBound = success;
+            finished = (CONNECT_SUCCESS == result);
+            isBound = finished;
         } catch (IOException e) {
             if (e instanceof ConnectException && !isBlocking()) {
                 status = SOCKET_STATUS_PENDING;
             } else {
-                close();
-                throw e;
+                if (isOpen()){
+                    close();
+                    finished = true;
+                }                
+                throw e;                
             }
         } finally {
-            end(success);
+            if (isBlocking()) {
+                end(finished);
+            }
         }
 
         // set the connected address.
         connectAddress = inetSocketAddress;
         synchronized (this) {
             if (isBlocking()) {
-                status = (success ? SOCKET_STATUS_CONNECTED
+                status = (finished ? SOCKET_STATUS_CONNECTED
                         : SOCKET_STATUS_UNCONNECTED);
             } else {
                 status = SOCKET_STATUS_PENDING;
             }
         }
-        return success;
+        return finished;
     }
 
     /*
@@ -330,7 +333,7 @@
 
         // finish result
         int result = EOF;
-        boolean success = false;
+        boolean finished = false;
 
         try {
             begin();
@@ -343,19 +346,22 @@
                         connectAddress.getAddress(), connectAddress.getPort(),
                         HY_PORT_SOCKET_STEP_CHECK, connectContext);
             }
-            success = (result == CONNECT_SUCCESS);
+            finished = (result == CONNECT_SUCCESS);
         } catch (ConnectException e) {
-            close();
+            if (isOpen()){
+                close();
+                finished = true;
+            }     
             throw e;
         } finally {
-            end(success);
+            end(finished);
         }
 
         synchronized (this) {
-            status = (success ? SOCKET_STATUS_CONNECTED : status);
-            isBound = success;
+            status = (finished ? SOCKET_STATUS_CONNECTED : status);
+            isBound = finished;
         }
-        return success;
+        return finished;
     }
 
     // -------------------------------------------------------------------
@@ -383,6 +389,9 @@
             throws IOException {
         if (isIndexValid(targets, offset, length)) {
             checkOpenConnected();
+            if (0 == calculateByteBufferArray(targets, offset, length)){
+                return 0;
+            }
             synchronized (readLock) {
                 long totalCount = 0;
                 for (int val = offset; val < offset + length; val++) {
@@ -391,6 +400,9 @@
                     if (EOF != readCount) {
                         totalCount = totalCount + readCount;
                     } else {
+                        if (0 == totalCount){
+                            totalCount = -1;
+                        }
                         break;
                     }
                 }
@@ -413,12 +425,12 @@
         if (!target.hasRemaining()) {
             return 0;
         }
-
         int readCount = 0;
-
         try {
-            begin();
             byte[] readArray = new byte[target.remaining()];
+            if (isBlocking()){
+                begin();
+            }
             readCount = networkSystem.read(fd, readArray, 0, readArray.length,
                     (isBlocking() ? TIMEOUT_BLOCK : TIMEOUT_NONBLOCK));
             if (EOF != readCount) {
@@ -433,7 +445,9 @@
             }
             throw e;
         } finally {
-            end(readCount > 0);
+            if (isBlocking()){
+                end(readCount > 0);
+            }
         }
     }
 
@@ -442,7 +456,13 @@
      * @see java.nio.channels.SocketChannel#write(java.nio.ByteBuffer)
      */
     public int write(ByteBuffer source) throws IOException {
+        if (null == source) {
+            throw new NullPointerException();
+        }
         checkOpenConnected();
+        if (!source.hasRemaining()) {
+            return 0;
+        }
         synchronized (writeLock) {
             return writeImpl(source);
         }
@@ -456,6 +476,9 @@
             throws IOException {
         if (isIndexValid(sources, offset, length)) {
             checkOpenConnected();
+            if (0 == calculateByteBufferArray(sources, offset, length)){
+                return 0;
+            }
             synchronized (writeLock) {
                 long writeCount = 0;
                 for (int val = offset; val < offset + length; val++) {
@@ -467,6 +490,13 @@
         throw new ArrayIndexOutOfBoundsException();
     }
 
+    private int calculateByteBufferArray(ByteBuffer[] sources, int offset, int length){
+        int sum = 0;
+        for (int val = offset; val < offset + length; val++) {
+            sum = sum + sources[val].remaining();
+        }
+        return sum;
+    }
     /*
      * wirte the source. return the count of bytes written.
      */
@@ -476,31 +506,34 @@
         }
         int writeCount = 0;
         try {
-            begin();
+            networkSystem.setNonBlocking(fd, !this.isBlocking());
             int pos = source.position();
-            byte[] array;
-            // FIXME enhance the perform
+            int length = source.remaining();
+            if (isBlocking()){
+                begin();
+            }
             if (source.hasArray()) {
-                array = source.array();
+                writeCount = networkSystem.write(fd, source.array(), pos,
+                        length);
             } else {
-                array = new byte[source.remaining()];
+                byte[] array = new byte[length];
                 source.get(array);
+                writeCount = networkSystem.write(fd, array, 0, length);
             }
-            networkSystem.setNonBlocking(fd, !this.isBlocking());
-            writeCount = networkSystem.write(fd, array, 0, array.length);
             source.position(pos + writeCount);
-            return writeCount;
         } catch (SocketException e) {
-            if (ERRMSG_SOCKET_NONBLOCKING_WOULD_BLOCK.equals(e.getMessage())) {
-                return writeCount;
-            }
             if (ERRORMSG_ASYNCHRONOUSCLOSE.equals(e.getMessage())) {
                 throw new AsynchronousCloseException();
             }
-            throw e;
+            if (!ERRMSG_SOCKET_NONBLOCKING_WOULD_BLOCK.equals(e.getMessage())) {
+                throw e;
+            }            
         } finally {
-            end(writeCount >= 0);
+            if (isBlocking()){
+                end(writeCount >= 0);
+            }
         }
+        return writeCount;
     }
 
     // -------------------------------------------------------------------

Modified: incubator/harmony/enhanced/classlib/trunk/modules/nio/src/test/java/org/apache/harmony/tests/java/nio/channels/SocketChannelTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/nio/src/test/java/org/apache/harmony/tests/java/nio/channels/SocketChannelTest.java?rev=411114&r1=411113&r2=411114&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/nio/src/test/java/org/apache/harmony/tests/java/nio/channels/SocketChannelTest.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/nio/src/test/java/org/apache/harmony/tests/java/nio/channels/SocketChannelTest.java Fri Jun  2 03:24:01 2006
@@ -31,6 +31,7 @@
 import java.nio.channels.IllegalBlockingModeException;
 import java.nio.channels.NoConnectionPendingException;
 import java.nio.channels.NotYetConnectedException;
+import java.nio.channels.ServerSocketChannel;
 import java.nio.channels.SocketChannel;
 import java.nio.channels.UnresolvedAddressException;
 import java.nio.channels.UnsupportedAddressTypeException;
@@ -158,28 +159,31 @@
         MockSocketChannel testMSChannelnull = new MockSocketChannel(null);
         MockSocketChannel testMSChannel = new MockSocketChannel(
                 SelectorProvider.provider());
-        ServerSocket testServer = new ServerSocket(1081);
+        ServerSocket testServer = new ServerSocket(Support_PortManager
+                .getNextPort());
         try {
-            this.channel1.read(byteBuf);
-            fail("Should throw NPE");
-        } catch (NullPointerException e) {
-            // correct
-        }
-        byteBuf = new java.nio.ByteBuffer[CAPACITY_NORMAL];
-        try {
-            this.channel1.read(byteBuf);
-            fail("Should throw NotYetConnectedException");
-        } catch (NotYetConnectedException e) {
-            // correct
+            try {
+                this.channel1.read(byteBuf);
+                fail("Should throw NPE");
+            } catch (NullPointerException e) {
+                // correct
+            }
+            byteBuf = new java.nio.ByteBuffer[CAPACITY_NORMAL];
+            try {
+                this.channel1.read(byteBuf);
+                fail("Should throw NotYetConnectedException");
+            } catch (NotYetConnectedException e) {
+                // correct
+            }
+            long readNum = CAPACITY_NORMAL;
+            readNum = testMSChannel.read(byteBuf);
+            assertEquals(0, readNum);
+            readNum = CAPACITY_NORMAL;
+            readNum = testMSChannelnull.read(byteBuf);
+            assertEquals(0, readNum);
+        } finally {
+            testServer.close();
         }
-        long readNum = CAPACITY_NORMAL;
-        readNum = testMSChannel.read(byteBuf);
-        assertEquals(0, readNum);
-        readNum = CAPACITY_NORMAL;
-        readNum = testMSChannelnull.read(byteBuf);
-        assertEquals(0, readNum);
-
-        testServer.close();
     }
 
     /*
@@ -2655,23 +2659,16 @@
         }
     }
 
-    public void testConfigureBlockingWhileRead() {
+    public void testConfigureBlockingWhileRead() throws IOException {
+        channel1.connect(localAddr1);
+        server1.accept();
+        assertTrue(this.channel1.isConnected());
+        new ReadThread(channel1).start();
         try {
-            channel1.connect(localAddr1);
-            server1.accept();
-            assertTrue(this.channel1.isConnected());
-            new ReadThread(channel1).start();
-            try {
-                Thread.sleep(2000);
-            } catch (InterruptedException e) {
-            }
-            channel1.configureBlocking(false);
-            assertFalse(channel1.isBlocking());
-
-        } catch (IOException e) {
-            fail("connections are not established correctly");
-        }
-
+            Thread.sleep(2000);
+        } catch (InterruptedException e) {}
+        channel1.configureBlocking(false);
+        assertFalse(channel1.isBlocking());
     }
 
     private static class ReadThread extends Thread {
@@ -2687,6 +2684,119 @@
                 channel.read(bf);
             } catch (IOException e) {
             }
+        }
+    }
+
+    /**
+     * @tests SocketChannel#read(ByteBuffer[], int, int) when remote server
+     *        closed
+     */
+    public void test_socketChannel_read_ByteBufferII_remoteClosed()
+            throws Exception {
+        // regression 1 for HARMONY-549
+        ServerSocketChannel ssc = ServerSocketChannel.open();
+        ssc.socket().bind(localAddr2);
+        SocketChannel sc = SocketChannel.open();
+        sc.connect(localAddr2);
+        ssc.accept().close();
+        ByteBuffer[] buf = { ByteBuffer.allocate(10) };
+        assertEquals(-1, sc.read(buf, 0, 1));
+        ssc.close();
+        sc.close();
+    }
+
+    /**
+     * @tests SocketChannel#write(ByteBuffer[], int, int)
+     */
+    public void test_socketChannel_write_ByteBufferII() throws Exception {
+        // regression 2 for HARMONY-549
+        ServerSocketChannel ssc = ServerSocketChannel.open();
+        ssc.socket().bind(localAddr2);
+        SocketChannel sc = SocketChannel.open();
+        sc.connect(localAddr2);
+        SocketChannel sock = ssc.accept();
+        ByteBuffer[] buf = { ByteBuffer.allocate(10), null };
+        try {
+            sc.write(buf, 0, 2);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        ssc.close();
+        sc.close();
+        ByteBuffer target = ByteBuffer.allocate(10);
+        assertEquals(-1, sock.read(target));
+    }
+
+    /**
+     * @tests SocketChannel#read(ByteBuffer[], int, int) with a null ByteBuffer
+     */
+    public void test_socketChannel_read_ByteBufferII_bufNULL() throws Exception {
+        // regression 3 for HARMONY-549
+        ServerSocketChannel ssc = ServerSocketChannel.open();
+        ssc.socket().bind(localAddr2);
+        SocketChannel sc = SocketChannel.open();
+        sc.connect(localAddr2);
+        ssc.accept();
+        ByteBuffer[] buf = new ByteBuffer[2];
+        buf[0] = ByteBuffer.allocate(1);
+        // let buf[1] be null
+        try {
+            sc.read(buf, 0, 2);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        ssc.close();
+        sc.close();
+    }
+
+    /**
+     * @tests SocketChannel#write(ByteBuffer) after close
+     */
+    public void test_socketChannel_write_close() throws Exception {
+        // regression 4 for HARMONY-549
+        ServerSocketChannel ssc = ServerSocketChannel.open();
+        ssc.socket().bind(localAddr2);
+        SocketChannel sc = SocketChannel.open();
+        sc.connect(localAddr2);
+        SocketChannel sock = ssc.accept();
+        ByteBuffer buf = null;
+        ssc.close();
+        sc.close();
+        try {
+            sc.write(buf);
+            fail("should throw NPE");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        sock.close();
+    }
+
+    /**
+     * @tests SocketChannel#write(ByteBuffer) if position is not zero
+     */
+    public void test_socketChannel_write_ByteBuffer_posNotZero()
+            throws Exception {
+        // regression 5 for HARMONY-549
+        final String testStr = "Hello World";
+        ByteBuffer readBuf = ByteBuffer.allocate(11);
+        ByteBuffer buf = ByteBuffer.wrap(testStr.getBytes());
+        ServerSocketChannel ssc = ServerSocketChannel.open();
+        ssc.socket().bind(localAddr2);
+        SocketChannel sc = SocketChannel.open();
+        sc.connect(localAddr2);
+        buf.position(2);
+        ssc.accept().write(buf);
+        assertEquals(9, sc.read(readBuf));
+        buf.flip();
+        readBuf.flip();
+        byte[] read = new byte[9];
+        byte[] write = new byte[11];
+        buf.get(write);
+        readBuf.get(read);
+        for (int i = 0; i < 9; i++) {
+            assertEquals(read[i], write[i + 2]);
         }
     }
 }