You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2007/02/06 18:26:13 UTC
svn commit: r504210 - in /harmony/enhanced/classlib/trunk/modules:
luni/src/main/java/org/apache/harmony/luni/platform/
nio/src/main/java/org/apache/harmony/nio/internal/
nio/src/test/java/common/org/apache/harmony/nio/tests/java/nio/channels/
Author: tellison
Date: Tue Feb 6 09:26:11 2007
New Revision: 504210
URL: http://svn.apache.org/viewvc?view=rev&rev=504210
Log:
Apply patch HARMONY-3122 ([classlib][nio]refine Selector.select() implementation)
Modified:
harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SelectorImpl.java
harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java
harmony/enhanced/classlib/trunk/modules/nio/src/test/java/common/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java
Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java?view=diff&rev=504210&r1=504209&r2=504210
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java Tue Feb 6 09:26:11 2007
@@ -170,9 +170,9 @@
public InetAddress getSocketLocalAddress(FileDescriptor aFD,
boolean preferIPv6Addresses);
- public int[] select(SelectableChannel[] readChannels,
- SelectableChannel[] writeChannels, long timeout)
- throws SocketException;
+ public int[] select(FileDescriptor[] readFDs,
+ FileDescriptor[] writeFDs, long timeout)
+ throws SocketException;
/*
* Query the IP stack for the local port to which this socket is bound.
Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java?view=diff&rev=504210&r1=504209&r2=504210
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java Tue Feb 6 09:26:11 2007
@@ -288,41 +288,18 @@
* SocketException @return int array, each int approve one of the * channel if OK
*/
- public int[] select(SelectableChannel[] readChannels,
- SelectableChannel[] writeChannels, long timeout)
+ public int[] select(FileDescriptor[] readFDs,
+ FileDescriptor[] writeFDs, long timeout)
throws SocketException {
-
- FileDescriptor fdHandler = null;
- int countRead = readChannels.length;
- int countWrite = writeChannels.length;
- int result = 0, val;
- FileDescriptor[] readFDs = new FileDescriptor[countRead];
+ int countRead = readFDs.length;
+ int countWrite = writeFDs.length;
+ int result = 0;
+ if (0 == countRead + countWrite) {
+ return (new int[0]);
+ }
int[] flags = new int[countRead + countWrite];
- if ((0 == readChannels.length) && (0 == writeChannels.length)) {
- return (new int[0]);
- }
- for (val = 0; val < countRead; val++, fdHandler = null) {
- SelectableChannel element = readChannels[val];
- if (element instanceof FileDescriptorHandler) {
- fdHandler = ((FileDescriptorHandler) element).getFD();
- }
- if (null != fdHandler) {
- readFDs[val] = fdHandler;
- }
- }
- FileDescriptor[] writeFDs = new FileDescriptor[countWrite];
- for (val = 0; val < countWrite; val++, fdHandler = null) {
- SelectableChannel element = writeChannels[val];
- if (element instanceof FileDescriptorHandler) {
- fdHandler = ((FileDescriptorHandler) element).getFD();
- }
- if (null != fdHandler) {
- writeFDs[val] = fdHandler;
- }
- }
-
- // handle timeout in native
+ // handle timeout in native
result = selectImpl(readFDs, writeFDs, countRead, countWrite, flags,
timeout);
Modified: harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SelectorImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SelectorImpl.java?view=diff&rev=504210&r1=504209&r2=504210
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SelectorImpl.java (original)
+++ harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/SelectorImpl.java Tue Feb 6 09:26:11 2007
@@ -15,6 +15,7 @@
*/
package org.apache.harmony.nio.internal;
+import java.io.FileDescriptor;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedSelectorException;
@@ -36,7 +37,7 @@
import java.util.List;
import java.util.Set;
-import org.apache.harmony.luni.platform.INetworkSystem;
+import org.apache.harmony.luni.platform.FileDescriptorHandler;
import org.apache.harmony.luni.platform.Platform;
/*
@@ -77,14 +78,20 @@
private Pipe.SinkChannel sink;
private Pipe.SourceChannel source;
+
+ private FileDescriptor sourcefd;
+
+ private SelectionKey[] readableChannels;
- private List<SelectableChannel> readableChannels = new ArrayList<SelectableChannel>();
+ private SelectionKey[] writableChannels;
- private List<SelectableChannel> writableChannels = new ArrayList<SelectableChannel>();
+ private List<FileDescriptor> readableFDs = new ArrayList<FileDescriptor>();
- private SelectableChannel[] readable;
+ private List<FileDescriptor> writableFDs = new ArrayList<FileDescriptor>();
- private SelectableChannel[] writable;
+ private FileDescriptor[] readable;
+
+ private FileDescriptor[] writable;
public SelectorImpl(SelectorProvider selectorProvider) {
super(selectorProvider);
@@ -92,6 +99,7 @@
Pipe mockSelector = selectorProvider.openPipe();
sink = mockSelector.sink();
source = mockSelector.source();
+ sourcefd = ((FileDescriptorHandler)source).getFD();
source.configureBlocking(false);
} catch (IOException e) {
// do nothing
@@ -172,7 +180,26 @@
synchronized (keys) {
synchronized (selectedKeys) {
doCancel();
- return selectImpl(timeout);
+ int[] readyChannels = null;
+ boolean isBlock = (SELECT_NOW != timeout);
+ if (keys.size() == 0) {
+ return 0;
+ }
+ prepareChannels();
+ try {
+ if (isBlock) {
+ begin();
+ }
+ readyChannels = Platform.getNetworkSystem().select(readable, writable, timeout);
+ } finally {
+ // clear results for next select
+ readableFDs.clear();
+ writableFDs.clear();
+ if (isBlock) {
+ end();
+ }
+ }
+ return processSelectResult(readyChannels);
}
}
}
@@ -188,25 +215,31 @@
// Prepares and adds channels to list for selection
private void prepareChannels() {
- readableChannels.add(source);
+ readableFDs.add(sourcefd);
+ List<SelectionKey> readChannelList = new ArrayList<SelectionKey>();
+ readChannelList.add(source.keyFor(this));
+ List<SelectionKey> writeChannelList = new ArrayList<SelectionKey>();
synchronized (keysLock) {
for (Iterator<SelectionKey> i = keys.iterator(); i.hasNext();) {
SelectionKeyImpl key = (SelectionKeyImpl) i.next();
key.oldInterestOps = key.interestOps();
boolean isReadableChannel = ((SelectionKey.OP_ACCEPT | SelectionKey.OP_READ) & key.oldInterestOps) != 0;
boolean isWritableChannel = ((SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE) & key.oldInterestOps) != 0;
+ SelectableChannel channel = key.channel();
if (isReadableChannel) {
- readableChannels.add(key.channel());
+ readChannelList.add(channel.keyFor(this));
+ readableFDs.add(((FileDescriptorHandler)channel).getFD());
}
if (isWritableChannel) {
- writableChannels.add(key.channel());
+ writeChannelList.add(channel.keyFor(this));
+ writableFDs.add(((FileDescriptorHandler)channel).getFD());
}
}
}
- readable = readableChannels.toArray(new SelectableChannel[0]);
- writable = writableChannels.toArray(new SelectableChannel[0]);
- readableChannels.clear();
- writableChannels.clear();
+ readableChannels = readChannelList.toArray(new SelectionKey[0]);
+ writableChannels = writeChannelList.toArray(new SelectionKey[0]);
+ readable = readableFDs.toArray(new FileDescriptor[0]);
+ writable = writableFDs.toArray(new FileDescriptor[0]);
}
// Analyses selected channels and adds keys of ready channels to
@@ -223,10 +256,10 @@
}
}
int selected = 0;
- for (int i = 1; i < readyChannels.length; i++) {
- SelectionKeyImpl key = (SelectionKeyImpl) (i >= readable.length ? writable[i
- - readable.length].keyFor(this)
- : readable[i].keyFor(this));
+ for (int i = 1; i < readyChannels.length; i++) {
+ SelectionKeyImpl key = (SelectionKeyImpl) (i >= readable.length ? writableChannels[i
+ - readable.length]
+ : readableChannels[i]);
if (null == key) {
continue;
}
@@ -261,28 +294,9 @@
}
}
}
+ readableChannels = null;
+ writableChannels = null;
return selected;
- }
-
- private int selectImpl(long timeout) throws IOException {
- INetworkSystem os = Platform.getNetworkSystem();
- int[] readyChannels = null;
- boolean isBlock = (SELECT_NOW != timeout);
- if (keys.size() == 0) {
- return 0;
- }
- prepareChannels();
- try {
- if (isBlock) {
- begin();
- }
- readyChannels = os.select(readable, writable, timeout);
- } finally {
- if (isBlock) {
- end();
- }
- }
- return processSelectResult(readyChannels);
}
/*
Modified: harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java?view=diff&rev=504210&r1=504209&r2=504210
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java (original)
+++ harmony/enhanced/classlib/trunk/modules/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java Tue Feb 6 09:26:11 2007
@@ -141,8 +141,8 @@
// for non blocking mode, use select to see whether
// there are any pending connections.
int[] tryResult = Platform.getNetworkSystem().select(
- new SelectableChannel[] { this },
- new SelectableChannel[0], 0);
+ new FileDescriptor[] { this.fd },
+ new FileDescriptor[0], 0);
if (0 == tryResult.length || 0 == tryResult[0]) {
// no pending connections, returns immediately.
return null;
Modified: harmony/enhanced/classlib/trunk/modules/nio/src/test/java/common/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/nio/src/test/java/common/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java?view=diff&rev=504210&r1=504209&r2=504210
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/nio/src/test/java/common/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/nio/src/test/java/common/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java Tue Feb 6 09:26:11 2007
@@ -1246,8 +1246,11 @@
public void testCFII_EmptyHost() throws Exception {
statusNotConnected_NotPending();
+ ServerSocket server = new ServerSocket(0);
+ int port = server.getLocalPort();
+ server.close();
try {
- this.channel1.connect(new InetSocketAddress("", 1081));
+ this.channel1.connect(new InetSocketAddress("", port));
fail("Should throw ConnectException");
} catch (ConnectException e) {
// correct
@@ -1952,9 +1955,42 @@
} catch (ClosedChannelException e) {
// correct
}
-
}
+ public void testReadByteBuffer_Direct() throws Exception {
+ assertTrue(this.server1.isBound());
+ java.nio.ByteBuffer readBuf = java.nio.ByteBuffer
+ .allocateDirect(CAPACITY_NORMAL);
+ assertFalse(this.channel1.isRegistered());
+ assertTrue(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ // note: blocking-mode will make the read process endless!
+ this.channel1.configureBlocking(false);
+ try {
+ channel1.read(readBuf);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ this.channel1.connect(localAddr1);
+ assertFalse(this.channel1.isBlocking());
+ assertTrue(this.channel1.isConnectionPending());
+ assertFalse(this.channel1.isConnected());
+ if (tryFinish()) {
+ assertEquals(0, this.channel1.read(readBuf));
+ }
+
+ this.channel1.close();
+ try {
+ channel1.read(readBuf);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
+
public void testReadByteBuffer_BufNull() throws Exception {
assertTrue(this.server1.isBound());
java.nio.ByteBuffer readBuf = java.nio.ByteBuffer.allocate(0);
@@ -2023,6 +2059,45 @@
// correct
}
}
+
+ /*
+ * SocketChannelImpl.read(ByteBuffer[], int, int)'
+ */
+ public void testReadByteBufferArrayIntInt_Direct() throws Exception {
+ assertTrue(this.server1.isBound());
+ java.nio.ByteBuffer[] readBuf = new java.nio.ByteBuffer[2];
+ readBuf[0] = java.nio.ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ readBuf[1] = java.nio.ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ assertFalse(this.channel1.isRegistered());
+ assertTrue(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ // note: blocking-mode will make the read process endless!
+ this.channel1.configureBlocking(false);
+ try {
+ channel1.read(readBuf, 0, 1);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ this.channel1.connect(localAddr1);
+ assertFalse(this.channel1.isBlocking());
+ assertTrue(this.channel1.isConnectionPending());
+ assertFalse(this.channel1.isConnected());
+ if (tryFinish()) {
+ assertEquals(0, this.channel1.read(readBuf, 0, 1));
+ assertEquals(0, this.channel1.read(readBuf, 0, 2));
+ }
+
+ this.channel1.close();
+ try {
+ channel1.read(readBuf, 0, 1);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
public void testReadByteBufferArrayIntInt_BufNull() throws Exception {
assertTrue(this.server1.isBound());
@@ -2098,6 +2173,37 @@
// correct
}
}
+
+ public void testWriteByteBuffer_Direct() throws IOException {
+ assertTrue(this.server1.isBound());
+ java.nio.ByteBuffer writeBuf = java.nio.ByteBuffer
+ .allocateDirect(CAPACITY_NORMAL);
+ assertFalse(this.channel1.isRegistered());
+ assertTrue(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ try {
+ channel1.write(writeBuf);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ this.channel1.connect(localAddr1);
+ assertTrue(this.channel1.isBlocking());
+ assertTrue(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf));
+
+ this.channel1.close();
+ try {
+ channel1.write(writeBuf);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
public void testWriteByteBuffer_BufNull() throws IOException {
assertTrue(this.server1.isBound());
@@ -2150,6 +2256,44 @@
}
}
+ /*
+ * SocketChannelImpl.write(ByteBuffer[], int, int)'
+ */
+ public void testWriteByteBufferArrayIntInt_Direct() throws IOException {
+ java.nio.ByteBuffer[] writeBuf = new java.nio.ByteBuffer[2];
+ writeBuf[0] = java.nio.ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ writeBuf[1] = java.nio.ByteBuffer.allocateDirect(CAPACITY_NORMAL);
+ assertFalse(this.channel1.isRegistered());
+ assertTrue(this.channel1.isBlocking());
+ assertFalse(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ try {
+ channel1.write(writeBuf, 0, 1);
+ fail("Should throw NotYetConnectedException");
+ } catch (NotYetConnectedException e) {
+ // correct
+ }
+ this.channel1.connect(localAddr1);
+ assertTrue(this.channel1.isBlocking());
+ assertTrue(this.channel1.isConnected());
+ assertFalse(this.channel1.isConnectionPending());
+ assertTrue(this.channel1.isOpen());
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf, 0, 1));
+ // still writes the same size as above
+ assertEquals(CAPACITY_NORMAL, this.channel1.write(writeBuf, 0, 2));
+ writeBuf[0].flip();
+ writeBuf[1].flip();
+ assertEquals(CAPACITY_NORMAL * 2, this.channel1.write(writeBuf, 0, 2));
+ this.channel1.close();
+ try {
+ channel1.write(writeBuf);
+ fail("Should throw ClosedChannelException");
+ } catch (ClosedChannelException e) {
+ // correct
+ }
+ }
+
public void testWriteByteBufferArrayIntInt_BufNull() throws IOException {
java.nio.ByteBuffer[] writeBuf = new java.nio.ByteBuffer[0];