diff options
author | Elliott Hughes <enh@google.com> | 2013-07-09 23:39:23 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2013-07-09 23:39:23 +0000 |
commit | 131dcd13038e931d75cd3a63d14df0527670f7f3 (patch) | |
tree | 229204c89a42c3d608daa216de6f7a60ceb05367 | |
parent | ec618403efee992f232f017fbff1afff6cfa0de3 (diff) | |
parent | 57656d21f772aacbe0d05e54b1274f4c58993a52 (diff) | |
download | libcore-131dcd13038e931d75cd3a63d14df0527670f7f3.zip libcore-131dcd13038e931d75cd3a63d14df0527670f7f3.tar.gz libcore-131dcd13038e931d75cd3a63d14df0527670f7f3.tar.bz2 |
Merge "Fix Selector to allow read and write at the same time."
-rw-r--r-- | luni/src/main/java/java/nio/SelectorImpl.java | 19 | ||||
-rw-r--r-- | luni/src/test/java/libcore/java/nio/channels/SelectorTest.java | 41 |
2 files changed, 45 insertions, 15 deletions
diff --git a/luni/src/main/java/java/nio/SelectorImpl.java b/luni/src/main/java/java/nio/SelectorImpl.java index 02fdf54..447157b 100644 --- a/luni/src/main/java/java/nio/SelectorImpl.java +++ b/luni/src/main/java/java/nio/SelectorImpl.java @@ -254,24 +254,25 @@ final class SelectorImpl extends AbstractSelector { pollFd.userData = null; int ops = key.interestOpsNoCheck(); - int selectedOp = 0; + int selectedOps = 0; if ((pollFd.revents & POLLIN) != 0) { - selectedOp = ops & (OP_ACCEPT | OP_READ); - } else if ((pollFd.revents & POLLOUT) != 0) { + selectedOps |= ops & (OP_ACCEPT | OP_READ); + } + if ((pollFd.revents & POLLOUT) != 0) { if (key.isConnected()) { - selectedOp = ops & OP_WRITE; + selectedOps |= ops & OP_WRITE; } else { - selectedOp = ops & OP_CONNECT; + selectedOps |= ops & OP_CONNECT; } } - if (selectedOp != 0) { + if (selectedOps != 0) { boolean wasSelected = mutableSelectedKeys.contains(key); - if (wasSelected && key.readyOps() != selectedOp) { - key.setReadyOps(key.readyOps() | selectedOp); + if (wasSelected && key.readyOps() != selectedOps) { + key.setReadyOps(key.readyOps() | selectedOps); ++readyKeyCount; } else if (!wasSelected) { - key.setReadyOps(selectedOp); + key.setReadyOps(selectedOps); mutableSelectedKeys.add(key); ++readyKeyCount; } diff --git a/luni/src/test/java/libcore/java/nio/channels/SelectorTest.java b/luni/src/test/java/libcore/java/nio/channels/SelectorTest.java index 4fc70c4..ec20c2a 100644 --- a/luni/src/test/java/libcore/java/nio/channels/SelectorTest.java +++ b/luni/src/test/java/libcore/java/nio/channels/SelectorTest.java @@ -18,6 +18,7 @@ package libcore.java.nio.channels; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; +import java.nio.ByteBuffer; import java.nio.channels.NoConnectionPendingException; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; @@ -129,16 +130,44 @@ public class SelectorTest extends TestCase { } } - /** - * We previously leaked a file descriptor for each selector instance created. - * - * http://code.google.com/p/android/issues/detail?id=5993 - * http://code.google.com/p/android/issues/detail?id=4825 - */ + // We previously leaked a file descriptor for each selector instance created. + // + // http://code.google.com/p/android/issues/detail?id=5993 + // http://code.google.com/p/android/issues/detail?id=4825 public void testLeakingPipes() throws IOException { for (int i = 0; i < 2000; i++) { Selector selector = Selector.open(); selector.close(); } } + + public void test_57456() throws Exception { + Selector selector = Selector.open(); + ServerSocketChannel ssc = ServerSocketChannel.open(); + + try { + // Connect. + ssc.configureBlocking(false); + ssc.socket().bind(null); + SocketChannel sc = SocketChannel.open(); + sc.connect(ssc.socket().getLocalSocketAddress()); + sc.finishConnect(); + + // Switch to non-blocking so we can use a Selector. + sc.configureBlocking(false); + + // Have the 'server' write something. + ssc.accept().write(ByteBuffer.allocate(128)); + + // At this point, the client should be able to read or write immediately. + // (It shouldn't be able to connect because it's already connected.) + SelectionKey key = sc.register(selector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE); + assertEquals(1, selector.select()); + assertEquals(SelectionKey.OP_READ | SelectionKey.OP_WRITE, key.readyOps()); + assertEquals(0, selector.select()); + } finally { + selector.close(); + ssc.close(); + } + } } |