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]);
}
}
}