1dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes/* Licensed to the Apache Software Foundation (ASF) under one or more
2dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes * contributor license agreements.  See the NOTICE file distributed with
3dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes * this work for additional information regarding copyright ownership.
4dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes * The ASF licenses this file to You under the Apache License, Version 2.0
5dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes * (the "License"); you may not use this file except in compliance with
6dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes * the License.  You may obtain a copy of the License at
72f6885fcf86bbe5c122eb751a5dd31d15a1cfbc3Elliott Hughes *
8dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes *     http://www.apache.org/licenses/LICENSE-2.0
92f6885fcf86bbe5c122eb751a5dd31d15a1cfbc3Elliott Hughes *
10dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes * Unless required by applicable law or agreed to in writing, software
11dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
12dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes * See the License for the specific language governing permissions and
14dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes * limitations under the License.
15dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes */
16dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
17e5fea3d504609d22337a5311d3ce0e72314bceeeNarayan Kamathpackage org.apache.harmony.tests.java.nio.channels;
18dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
19dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughesimport java.io.IOException;
20dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughesimport java.net.ServerSocket;
21067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughesimport java.net.SocketAddress;
22dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughesimport java.nio.ByteBuffer;
23dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughesimport java.nio.channels.ClosedChannelException;
24dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughesimport java.nio.channels.ClosedSelectorException;
25dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughesimport java.nio.channels.Pipe;
26dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughesimport java.nio.channels.SelectionKey;
27dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughesimport java.nio.channels.Selector;
28dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughesimport java.nio.channels.ServerSocketChannel;
29dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughesimport java.nio.channels.SocketChannel;
30dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughesimport java.nio.channels.spi.SelectorProvider;
31dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughesimport java.util.concurrent.atomic.AtomicBoolean;
32dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughesimport java.util.concurrent.atomic.AtomicReference;
33067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughesimport java.util.Set;
34dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughesimport junit.framework.TestCase;
35dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
36dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes/*
37dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes * Tests for Selector and its default implementation
38dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes */
39dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughespublic class SelectorTest extends TestCase {
40dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    private static final int WAIT_TIME = 100;
41dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
42067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughes    private SocketAddress localAddress;
43dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
44067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughes    private Selector selector;
45dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
46067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughes    private ServerSocketChannel ssc;
47dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
48067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughes    private enum SelectType {
49dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        NULL, TIMEOUT, NOW
50dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    };
51dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
52dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    protected void setUp() throws Exception {
53dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        super.setUp();
54dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        ssc = ServerSocketChannel.open();
55dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        ssc.configureBlocking(false);
56dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        ServerSocket ss = ssc.socket();
57067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughes        ss.bind(null);
58067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughes        localAddress = ss.getLocalSocketAddress();
59dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        selector = Selector.open();
60dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
61dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
62dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    protected void tearDown() throws Exception {
63dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        try {
64dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            ssc.close();
65dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } catch (Exception e) {
66dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // do nothing
67dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
68dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        try {
69dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            selector.close();
70dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } catch (Exception e) {
71dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // do nothing
72dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
73dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        super.tearDown();
74dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
75dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
76dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    /**
77dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * @tests java.nio.channels.Selector#open()
78dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     */
79dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_open() throws IOException {
80dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertNotNull(selector);
81dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
82dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
83dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    /**
84dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * @tests Selector#isOpen()
85dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     */
86dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_isOpen() throws IOException {
87dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertTrue(selector.isOpen());
88dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        selector.close();
89dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertFalse(selector.isOpen());
90dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
91dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
92dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    /**
93dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * @tests java.nio.channels.Selector#provider()
94dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     */
95dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_provider() throws IOException {
96dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        // should be system default provider
97dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertNotNull(selector.provider());
98dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertSame(SelectorProvider.provider(), selector.provider());
99dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
100dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
101dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    /**
102dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * @tests java.nio.channels.Selector#keys()
103dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     */
104dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_keys() throws IOException {
105dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SelectionKey key = ssc.register(selector, SelectionKey.OP_ACCEPT);
1062f6885fcf86bbe5c122eb751a5dd31d15a1cfbc3Elliott Hughes
107dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        Set<SelectionKey> keySet = selector.keys();
108dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        Set<SelectionKey> keySet2 = selector.keys();
1092f6885fcf86bbe5c122eb751a5dd31d15a1cfbc3Elliott Hughes
110dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertSame(keySet, keySet2);
111dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertEquals(1,keySet.size());
112dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SelectionKey key2 = keySet.iterator().next();
113dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertEquals(key,key2);
114dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
115dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        // Any attempt to modify keys will cause UnsupportedOperationException
116dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SocketChannel sc = SocketChannel.open();
117dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        sc.configureBlocking(false);
118dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SelectionKey key3 = sc.register(selector, SelectionKey.OP_READ);
119dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        try {
120dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            keySet2.add(key3);
121dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            fail("should throw UnsupportedOperationException");
122dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } catch (UnsupportedOperationException e) {
123dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // expected
124dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
125dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        try {
126dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            keySet2.remove(key3);
127dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            fail("should throw UnsupportedOperationException");
128dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } catch (UnsupportedOperationException e) {
129dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // expected
130dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
131dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        try {
132dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            keySet2.clear();
133dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            fail("should throw UnsupportedOperationException");
134dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } catch (UnsupportedOperationException e) {
135dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // expected
136dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
137dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
138dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        selector.close();
139dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        try {
140dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            selector.keys();
141dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            fail("should throw ClosedSelectorException");
142dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } catch (ClosedSelectorException e) {
143dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // expected
144dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
145dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
146dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
147dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    /**
148dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * @tests java.nio.channels.Selector#keys()
149dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     */
150dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_selectedKeys() throws IOException {
151dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SocketChannel sc = SocketChannel.open();
152dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        ssc.register(selector, SelectionKey.OP_ACCEPT);
153dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        try {
154dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            int count = 0;
155067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughes            sc.connect(localAddress);
156dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            count = blockingSelect(SelectType.NULL, 0);
157dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(1, count);
158dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            Set<SelectionKey> selectedKeys = selector.selectedKeys();
159dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            Set<SelectionKey> selectedKeys2 = selector.selectedKeys();
160dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertSame(selectedKeys, selectedKeys2);
161dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
162dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(1, selectedKeys.size());
163dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(ssc.keyFor(selector), selectedKeys.iterator().next());
164dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // add one key into selectedKeys
165dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            try {
166dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                selectedKeys.add(ssc.keyFor(selector));
167dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                fail("Should throw UnsupportedOperationException");
168dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            } catch (UnsupportedOperationException e) {
169dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                // expected
170dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
171dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
172dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // no exception should be thrown
173dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            selectedKeys.clear();
174dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
175dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            Set<SelectionKey> selectedKeys3 = selector.selectedKeys();
176dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertSame(selectedKeys, selectedKeys3);
177dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
178dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            ssc.keyFor(selector).cancel();
179dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(0, selectedKeys.size());
180dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            selector.close();
181dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            try {
182dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                selector.selectedKeys();
183dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                fail("should throw ClosedSelectorException");
184dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            } catch (ClosedSelectorException e) {
185dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                // expected
186dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
187dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } finally {
188dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            sc.close();
189dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
190dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
191dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
192dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    /**
193dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * @tests java.nio.channel.Selector#selectNow()
194dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     */
195dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_selectNow() throws IOException {
196dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_ACCEPT(SelectType.NOW, 0);
197dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_CONNECT(SelectType.NOW, 0);
198dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_READ(SelectType.NOW, 0);
199dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_WRITE(SelectType.NOW, 0);
200dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
201dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
202dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    /**
203dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * @tests java.nio.channel.Selector#selectNow()
204dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     */
205dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_selectNow_SelectorClosed() throws IOException {
206dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_SelectorClosed(SelectType.NOW, 0);
207dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
208dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
209dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_selectNow_Timeout() throws IOException {
210dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        // make sure selectNow doesn't block
211dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        selector.selectNow();
212dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
213dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
214dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    /**
215dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * @tests java.nio.channel.Selector#select()
216dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     */
217dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_select() throws IOException {
218dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_ACCEPT(SelectType.NULL, 0);
219dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_CONNECT(SelectType.NULL, 0);
220dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_READ(SelectType.NULL, 0);
221dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_WRITE(SelectType.NULL, 0);
222dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
223dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
224dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    /**
225dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * @tests java.nio.channel.Selector#select()
226dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     */
227dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_select_SelectorClosed() throws IOException {
228dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_SelectorClosed(SelectType.NULL, 0);
229dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
230dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
231dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    /**
232dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * @tests java.nio.channel.Selector#select(long)
233dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     */
234dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_selectJ() throws IOException {
235dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_ACCEPT(SelectType.TIMEOUT, 0);
236dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_CONNECT(SelectType.TIMEOUT, 0);
237dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_READ(SelectType.TIMEOUT, 0);
238dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_WRITE(SelectType.TIMEOUT, 0);
239dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
240dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_ACCEPT(SelectType.TIMEOUT, WAIT_TIME);
241dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_CONNECT(SelectType.TIMEOUT, WAIT_TIME);
242dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_READ(SelectType.TIMEOUT, WAIT_TIME);
243dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_OP_WRITE(SelectType.TIMEOUT, WAIT_TIME);
244dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
245dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
246dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    /**
247dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * @tests java.nio.channel.Selector#select(long)
248dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     */
249dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_selectJ_SelectorClosed() throws IOException {
250dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_SelectorClosed(SelectType.TIMEOUT, 0);
251dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        selector = Selector.open();
252dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assert_select_SelectorClosed(SelectType.TIMEOUT, WAIT_TIME);
253dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
254dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
255dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    /**
256dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * @tests java.nio.channel.Selector#select(long)
257dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     */
258dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_selectJ_Exception() throws IOException {
259dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        try {
260dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            selector.select(-1);
261dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } catch (IllegalArgumentException e) {
262dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // expected
263dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
264dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
265dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
266dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_selectJ_Timeout() throws IOException {
267dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        // make sure select(timeout) doesn't block
268dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        selector.select(WAIT_TIME);
269dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
270dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
271dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_selectJ_Empty_Keys() throws IOException {
272dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        // regression test, see HARMONY-3888.
273dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        // make sure select(long) does wait for specified amount of
274dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        // time if keys.size() == 0 (initial state of selector).
275dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
2762f6885fcf86bbe5c122eb751a5dd31d15a1cfbc3Elliott Hughes        final long SELECT_TIMEOUT_MS = 2000;
2772f6885fcf86bbe5c122eb751a5dd31d15a1cfbc3Elliott Hughes
2782f6885fcf86bbe5c122eb751a5dd31d15a1cfbc3Elliott Hughes        long t0 = System.nanoTime();
2792f6885fcf86bbe5c122eb751a5dd31d15a1cfbc3Elliott Hughes        selector.select(SELECT_TIMEOUT_MS);
2802f6885fcf86bbe5c122eb751a5dd31d15a1cfbc3Elliott Hughes        long t1 = System.nanoTime();
281dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
2822f6885fcf86bbe5c122eb751a5dd31d15a1cfbc3Elliott Hughes        long waitMs = (t1 - t0) / 1000L / 1000L;
2832f6885fcf86bbe5c122eb751a5dd31d15a1cfbc3Elliott Hughes        assertTrue(waitMs >= SELECT_TIMEOUT_MS);
2842f6885fcf86bbe5c122eb751a5dd31d15a1cfbc3Elliott Hughes        assertTrue(waitMs < 5*SELECT_TIMEOUT_MS);
285dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
286dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
287dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    /**
288dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * @tests java.nio.channels.Selector#wakeup()
289dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     */
290dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_wakeup() throws IOException {
291dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        /*
292dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes         * make sure the test does not block on select
293dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes         */
294dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        selector.wakeup();
295dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        selectOnce(SelectType.NULL, 0);
296dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        selector.wakeup();
297dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        selectOnce(SelectType.TIMEOUT, 0);
298dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
299dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        // try to wakeup select. The invocation sequence of wakeup and select
300dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        // doesn't affect test result.
301dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        new Thread() {
302dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            public void run() {
303dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
304dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                try {
305dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                    Thread.sleep(WAIT_TIME);
306dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                } catch (InterruptedException e) {
307dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                    // ignore
308dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                }
309dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                selector.wakeup();
310dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
311dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }.start();
312dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        selectOnce(SelectType.NULL, 0);
313dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
314dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        // try to wakeup select. The invocation sequence of wakeup and select
315dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        // doesn't affect test result.
316dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        new Thread() {
317dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            public void run() {
318dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
319dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                try {
320dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                    Thread.sleep(WAIT_TIME);
321dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                } catch (InterruptedException e) {
322dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                    // ignore
323dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                }
324dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                selector.wakeup();
325dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
326dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }.start();
327dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        selectOnce(SelectType.TIMEOUT, 0);
328dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
329dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
330dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_keySetViewsModifications() throws IOException {
331dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        Set<SelectionKey> keys = selector.keys();
332dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
333dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SelectionKey key1 = ssc.register(selector, SelectionKey.OP_ACCEPT);
334dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
335dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertTrue(keys.contains(key1));
336dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
337dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SocketChannel sc = SocketChannel.open();
338dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        sc.configureBlocking(false);
339dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SelectionKey key2 = sc.register(selector, SelectionKey.OP_READ);
340dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
341dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertTrue(keys.contains(key1));
342dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertTrue(keys.contains(key2));
343dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
344dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        key1.cancel();
345dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertTrue(keys.contains(key1));
346dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
347dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        selector.selectNow();
348dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertFalse(keys.contains(key1));
349dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertTrue(keys.contains(key2));
350dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     }
351dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
352dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    /**
353dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * This test cancels a key while selecting to verify that the cancelled
354dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * key set is processed both before and after the call to the underlying
355dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     * operating system.
356dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes     */
357dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_cancelledKeys() throws Exception {
358dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        final AtomicReference<Throwable> failure = new AtomicReference<Throwable>();
359dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        final AtomicBoolean complete = new AtomicBoolean();
360dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
361dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        final Pipe pipe = Pipe.open();
362dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        pipe.source().configureBlocking(false);
363dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        final SelectionKey key = pipe.source().register(selector, SelectionKey.OP_READ);
364dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
365dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        Thread thread = new Thread() {
366dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            public void run() {
367dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                try {
368dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                    // make sure to call key.cancel() while the main thread is selecting
369dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                    Thread.sleep(500);
370dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                    key.cancel();
371dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                    assertFalse(key.isValid());
372dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                    pipe.sink().write(ByteBuffer.allocate(4)); // unblock select()
373dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                } catch (Throwable e) {
374dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                    failure.set(e);
375dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                } finally {
376dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                    complete.set(true);
377dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                }
378dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
379dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        };
380dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertTrue(key.isValid());
381dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
382dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        thread.start();
383dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        do {
384dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(0, selector.select(5000)); // blocks
385dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(0, selector.selectedKeys().size());
386dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } while (!complete.get()); // avoid spurious interrupts
387dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertFalse(key.isValid());
388dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
389dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        thread.join();
390dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        assertNull(failure.get());
391dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
392dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
393dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void testOpChange() throws Exception {
394dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SocketChannel sc = SocketChannel.open();
395dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        sc.configureBlocking(false);
396dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        sc.register(selector, SelectionKey.OP_CONNECT);
397dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        try {
398067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughes            sc.connect(localAddress);
399dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            int count = blockingSelect(SelectType.TIMEOUT, 100);
400dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(1, count);
401dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            Set<SelectionKey> selectedKeys = selector.selectedKeys();
402dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(1, selectedKeys.size());
403dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            SelectionKey key = selectedKeys.iterator().next();
404dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(sc.keyFor(selector), key);
405dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(SelectionKey.OP_CONNECT, key.readyOps());
406dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // select again, it should return 0
407dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            count = selectOnce(SelectType.TIMEOUT, 100);
408dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(0, count);
409dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // but selectedKeys remains the same as previous
410dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertSame(selectedKeys, selector.selectedKeys());
411dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            sc.finishConnect();
412dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
413dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // same selector, but op is changed
414dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            SelectionKey key1 = sc.register(selector, SelectionKey.OP_WRITE);
415dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(key, key1);
416dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            count = blockingSelect(SelectType.TIMEOUT, 100);
417dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(1, count);
418dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            selectedKeys = selector.selectedKeys();
419dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(1, selectedKeys.size());
420dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            key = selectedKeys.iterator().next();
421dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(key, key1);
422dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(SelectionKey.OP_WRITE, key.readyOps());
423dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
424dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            selectedKeys.clear();
425dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } finally {
426dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            try {
427dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                ssc.accept().close();
428dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            } catch (Exception e) {
429dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                // do nothing
430dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
431dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            try {
432dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                sc.close();
433dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            } catch (IOException e) {
434dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                // do nothing
435dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
436dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
437dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
438dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
439dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    public void test_nonBlockingConnect() throws IOException {
440dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SocketChannel channel = null;
441dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        try {
442dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            channel = SocketChannel.open();
443dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            channel.configureBlocking(false);
444dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            Selector selector = Selector.open();
445dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            channel.register(selector, SelectionKey.OP_CONNECT);
446067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughes            channel.connect(localAddress);
447dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            channel.finishConnect();
448dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            selector.select();
449067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughes            assertEquals(0, selector.selectedKeys().size());
450dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } finally {
451dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            channel.close();
452dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
453dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
454dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
455dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    private void assert_select_SelectorClosed(SelectType type, int timeout)
456dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            throws IOException {
457dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        // selector is closed
458dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        selector.close();
459dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        try {
460dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            selectOnce(type, timeout);
461dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            fail("should throw ClosedSelectorException");
462dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } catch (ClosedSelectorException e) {
463dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // expected
464dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
465dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
466dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
467dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    private void assert_select_OP_ACCEPT(SelectType type, int timeout)
468dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            throws IOException, ClosedChannelException {
469dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SocketChannel sc = SocketChannel.open();
470dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SocketChannel client = null;
471dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        try {
472dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            ssc.register(selector, SelectionKey.OP_ACCEPT);
473067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughes            sc.connect(localAddress);
474dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            int count = blockingSelect(type, timeout);
475dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(1, count);
476dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            Set<SelectionKey> selectedKeys = selector.selectedKeys();
477dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(1, selectedKeys.size());
478dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            SelectionKey key = selectedKeys.iterator().next();
479dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(ssc.keyFor(selector), key);
480dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(SelectionKey.OP_ACCEPT, key.readyOps());
481dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // select again, it should return 0
482dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            count = selectOnce(type, timeout);
483dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(0,count);
484dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // but selectedKeys remains the same as previous
485dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertSame(selectedKeys, selector.selectedKeys());
486dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            client = ssc.accept();
487dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            selectedKeys.clear();
488dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } finally {
489dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            try {
490dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                sc.close();
491dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            } catch (IOException e) {
492dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                // do nothing
493dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
494dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            if (null != client) {
495dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                client.close();
496dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
497dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
498dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        ssc.keyFor(selector).cancel();
499dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
500dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
501dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    private void assert_select_OP_CONNECT(SelectType type, int timeout)
502dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            throws IOException, ClosedChannelException {
503dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SocketChannel sc = SocketChannel.open();
504dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        sc.configureBlocking(false);
505dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        sc.register(selector, SelectionKey.OP_CONNECT);
506dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        try {
507067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughes            sc.connect(localAddress);
508dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            int count = blockingSelect(type, timeout);
509dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(1, count);
510dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            Set<SelectionKey> selectedKeys = selector.selectedKeys();
511dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(1, selectedKeys.size());
512dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            SelectionKey key = selectedKeys.iterator().next();
513dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(sc.keyFor(selector), key);
514dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(SelectionKey.OP_CONNECT, key.readyOps());
515dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // select again, it should return 0
516dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            count = selectOnce(type, timeout);
517dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(0, count);
518dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // but selectedKeys remains the same as previous
519dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertSame(selectedKeys, selector.selectedKeys());
5202f6885fcf86bbe5c122eb751a5dd31d15a1cfbc3Elliott Hughes            sc.finishConnect();
521dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            selectedKeys.clear();
522dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } finally {
523dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            try {
524dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                ssc.accept().close();
525dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            } catch (Exception e) {
526dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                // do nothing
527dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
5282f6885fcf86bbe5c122eb751a5dd31d15a1cfbc3Elliott Hughes
529dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            try {
530dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                sc.close();
531dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            } catch (IOException e) {
532dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                // do nothing
533dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
534dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
535dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
536dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
537dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    private void assert_select_OP_READ(SelectType type, int timeout)
538dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            throws IOException {
539dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SocketChannel sc = SocketChannel.open();
540dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SocketChannel client = null;
541dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SocketChannel sc2 = SocketChannel.open();
542dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SocketChannel client2 = null;
543dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        try {
544dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            ssc.configureBlocking(true);
545067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughes            sc.connect(localAddress);
546dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            client = ssc.accept();
547dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            sc.configureBlocking(false);
548dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            sc.register(selector, SelectionKey.OP_READ);
549dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            client.configureBlocking(true);
550dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
551067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughes            sc2.connect(localAddress);
552dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            client2 = ssc.accept();
553dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            sc2.configureBlocking(false);
554dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            sc2.register(selector, SelectionKey.OP_READ);
555dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            client2.configureBlocking(true);
556dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
557dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            client.write(ByteBuffer.wrap("a".getBytes()));
558dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            int count = blockingSelect(type, timeout);
559dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(1, count);
560dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            Set<SelectionKey> selectedKeys = selector.selectedKeys();
561dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(1, selectedKeys.size());
562dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            SelectionKey key = selectedKeys.iterator().next();
563dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(sc.keyFor(selector), key);
564dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(SelectionKey.OP_READ, key.readyOps());
565dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // select again, it should return 0
566dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            count = selectOnce(type, timeout);
567dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(0, count);
568dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // but selectedKeys remains the same as previous
569dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertSame(selectedKeys, selector.selectedKeys());
570dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
571dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            sc.read(ByteBuffer.allocate(8));
572dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
573dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // the second SocketChannel should be selected this time
574dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            client2.write(ByteBuffer.wrap("a".getBytes()));
575dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            count = blockingSelect(type, timeout);
576dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(1, count);
577dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // selectedKeys still includes the key of sc, because the key of sc
578dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // is not removed last time.
579dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            selectedKeys = selector.selectedKeys();
580dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(2, selectedKeys.size());
581dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } finally {
582dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            if (null != client) {
583dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                try {
584dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                    client.close();
585dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                } catch (Exception e) {
586dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                    // ignore
587dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                }
588dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
589dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            if (null != client2) {
590dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                try {
591dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                    client2.close();
592dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                } catch (Exception e) {
593dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                    // ignore
594dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                }
595dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
596dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            try {
597dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                sc.close();
598dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            } catch (Exception e) {
599dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                // ignore
600dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
601dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            try {
602dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                sc2.close();
603dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            } catch (Exception e) {
604dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                // ignore
605dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
606dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            ssc.configureBlocking(false);
607dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
608dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
609dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
610dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    private void assert_select_OP_WRITE(SelectType type, int timeout)
611dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            throws IOException {
612dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SocketChannel sc = SocketChannel.open();
613dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        SocketChannel client = null;
614dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        try {
615067e5d68f30887f1d53bf6afde6007beb749e2c5Elliott Hughes            sc.connect(localAddress);
616dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            ssc.configureBlocking(true);
617dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            client = ssc.accept();
618dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            sc.configureBlocking(false);
619dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            sc.register(selector, SelectionKey.OP_WRITE);
620dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            int count = blockingSelect(type, timeout);
621dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(1, count);
622dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            Set<SelectionKey> selectedKeys = selector.selectedKeys();
623dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(1, selectedKeys.size());
624dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            SelectionKey key = selectedKeys.iterator().next();
625dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(sc.keyFor(selector), key);
626dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(SelectionKey.OP_WRITE, key.readyOps());
627dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // select again, it should return 0
628dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            count = selectOnce(type, timeout);
629dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertEquals(0, count);
630dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            // but selectedKeys remains the same as previous
631dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            assertSame(selectedKeys, selector.selectedKeys());
632dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } finally {
633dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            if (null != client) {
634dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                client.close();
635dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
636dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            try {
637dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                sc.close();
638dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            } catch (IOException e) {
639dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                // do nothing
640dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
641dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            ssc.configureBlocking(false);
642dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
643dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
644dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
645dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    private int blockingSelect(SelectType type, int timeout) throws IOException {
646dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        int ret = 0;
647dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        do {
648dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            ret = selectOnce(type, timeout);
649dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            if (ret > 0) {
650dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                return ret;
651dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
652dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            try {
653dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                Thread.sleep(100);
654dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            } catch (InterruptedException e) {
655dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes                // ignore
656dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            }
657dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        } while (true);
658dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
659dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
660dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    private int selectOnce(SelectType type, int timeout) throws IOException {
661dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        int ret = 0;
662dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        switch (type) {
663dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        case NULL:
664dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            ret = selector.select();
665dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            break;
666dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        case TIMEOUT:
667dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            ret = selector.select(timeout);
668dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            break;
669dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        case NOW:
670dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            ret = selector.selectNow();
671dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes            break;
672dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        }
673dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes        return ret;
674dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes    }
675dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes
676dce2b2fa9d6b26414a8d5a55918e4d7ca2ab1baaElliott Hughes}
677