Search in sources :

Example 1 with SelectableChannel

use of java.nio.channels.SelectableChannel in project jetty.project by eclipse.

the class SelectChannelEndPointTest method testRejectedExecution.

// TODO make this test reliable
@Test
@Ignore
public void testRejectedExecution() throws Exception {
    _manager.stop();
    _threadPool.stop();
    final CountDownLatch latch = new CountDownLatch(1);
    BlockingQueue<Runnable> q = new ArrayBlockingQueue<>(4);
    _threadPool = new QueuedThreadPool(4, 4, 60000, q);
    _manager = new SelectorManager(_threadPool, _scheduler, 1) {

        @Override
        protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey selectionKey) throws IOException {
            SocketChannelEndPoint endp = new SocketChannelEndPoint(channel, selector, selectionKey, getScheduler());
            _lastEndPoint = endp;
            _lastEndPointLatch.countDown();
            return endp;
        }

        @Override
        public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) throws IOException {
            return new TestConnection(endpoint, latch);
        }
    };
    _threadPool.start();
    _manager.start();
    AtomicInteger timeout = new AtomicInteger();
    AtomicInteger rejections = new AtomicInteger();
    AtomicInteger echoed = new AtomicInteger();
    CountDownLatch closed = new CountDownLatch(20);
    for (int i = 0; i < 20; i++) {
        new Thread() {

            public void run() {
                try (Socket client = newClient()) {
                    client.setSoTimeout(5000);
                    SocketChannel server = _connector.accept();
                    server.configureBlocking(false);
                    _manager.accept(server);
                    // Write client to server
                    client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8));
                    client.getOutputStream().flush();
                    client.shutdownOutput();
                    // Verify echo server to client
                    for (char c : "HelloWorld".toCharArray()) {
                        int b = client.getInputStream().read();
                        assertTrue(b > 0);
                        assertEquals(c, (char) b);
                    }
                    assertEquals(-1, client.getInputStream().read());
                    echoed.incrementAndGet();
                } catch (SocketTimeoutException x) {
                    x.printStackTrace();
                    timeout.incrementAndGet();
                } catch (Throwable x) {
                    rejections.incrementAndGet();
                } finally {
                    closed.countDown();
                }
            }
        }.start();
    }
    // unblock the handling
    latch.countDown();
    // wait for all clients to complete or fail
    closed.await();
    // assert some clients must have been rejected
    Assert.assertThat(rejections.get(), Matchers.greaterThan(0));
    // but not all of them
    Assert.assertThat(rejections.get(), Matchers.lessThan(20));
    // none should have timed out
    Assert.assertThat(timeout.get(), Matchers.equalTo(0));
    // and the rest should have worked
    Assert.assertThat(echoed.get(), Matchers.equalTo(20 - rejections.get()));
    // and the selector is still working for new requests
    try (Socket client = newClient()) {
        client.setSoTimeout(5000);
        SocketChannel server = _connector.accept();
        server.configureBlocking(false);
        _manager.accept(server);
        // Write client to server
        client.getOutputStream().write("HelloWorld".getBytes(StandardCharsets.UTF_8));
        client.getOutputStream().flush();
        client.shutdownOutput();
        // Verify echo server to client
        for (char c : "HelloWorld".toCharArray()) {
            int b = client.getInputStream().read();
            assertTrue(b > 0);
            assertEquals(c, (char) b);
        }
        assertEquals(-1, client.getInputStream().read());
    }
}
Also used : SelectionKey(java.nio.channels.SelectionKey) SocketChannel(java.nio.channels.SocketChannel) ServerSocketChannel(java.nio.channels.ServerSocketChannel) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) SocketTimeoutException(java.net.SocketTimeoutException) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) SelectableChannel(java.nio.channels.SelectableChannel) QueuedThreadPool(org.eclipse.jetty.util.thread.QueuedThreadPool) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Socket(java.net.Socket) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 2 with SelectableChannel

use of java.nio.channels.SelectableChannel in project netty by netty.

the class NioEventLoop method processSelectedKeysOptimized.

private void processSelectedKeysOptimized() {
    for (int i = 0; i < selectedKeys.size; ++i) {
        final SelectionKey k = selectedKeys.keys[i];
        // null out entry in the array to allow to have it GC'ed once the Channel close
        // See https://github.com/netty/netty/issues/2363
        selectedKeys.keys[i] = null;
        final Object a = k.attachment();
        if (a instanceof AbstractNioChannel) {
            processSelectedKey(k, (AbstractNioChannel) a);
        } else {
            @SuppressWarnings("unchecked") NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;
            processSelectedKey(k, task);
        }
        if (needsToSelectAgain) {
            // null out entries in the array to allow to have it GC'ed once the Channel close
            // See https://github.com/netty/netty/issues/2363
            selectedKeys.reset(i + 1);
            selectAgain();
            i = -1;
        }
    }
}
Also used : SelectionKey(java.nio.channels.SelectionKey) SelectableChannel(java.nio.channels.SelectableChannel)

Example 3 with SelectableChannel

use of java.nio.channels.SelectableChannel in project blade by biezhi.

the class ManagedSelector method processConnect.

private Runnable processConnect(SelectionKey key, final Connect connect) {
    SelectableChannel channel = key.channel();
    try {
        key.attach(connect.attachment);
        boolean connected = _selectorManager.doFinishConnect(channel);
        if (LOG.isDebugEnabled())
            LOG.debug("Connected {} {}", connected, channel);
        if (connected) {
            if (connect.timeout.cancel()) {
                key.interestOps(0);
                return new CreateEndPoint(channel, key) {

                    @Override
                    protected void failed(Throwable failure) {
                        super.failed(failure);
                        connect.failed(failure);
                    }
                };
            } else {
                throw new SocketTimeoutException("Concurrent Connect Timeout");
            }
        } else {
            throw new ConnectException();
        }
    } catch (Throwable x) {
        connect.failed(x);
        return null;
    }
}
Also used : SocketTimeoutException(java.net.SocketTimeoutException) SelectableChannel(java.nio.channels.SelectableChannel) ConnectException(java.net.ConnectException)

Example 4 with SelectableChannel

use of java.nio.channels.SelectableChannel in project hazelcast by hazelcast.

the class NonBlockingIOThread method rebuildSelector.

// this method is always invoked in this thread
// after we have blocked for selector.select in #runSelectLoopWithSelectorFix
private void rebuildSelector() {
    selectorRebuildCount.inc();
    Selector newSelector = newSelector(logger);
    Selector oldSelector = this.selector;
    // reset each handler's selectionKey, cancel the old keys
    for (SelectionKey key : oldSelector.keys()) {
        AbstractHandler handler = (AbstractHandler) key.attachment();
        SelectableChannel channel = key.channel();
        try {
            int ops = key.interestOps();
            SelectionKey newSelectionKey = channel.register(newSelector, ops, handler);
            handler.setSelectionKey(newSelectionKey);
        } catch (ClosedChannelException e) {
            logger.info("Channel was closed while trying to register with new selector.");
        } catch (CancelledKeyException e) {
            // a CancelledKeyException may be thrown in key.interestOps
            // in this case, since the key is already cancelled, just do nothing
            EmptyStatement.ignore(e);
        }
        key.cancel();
    }
    // close the old selector and substitute with new one
    closeSelector();
    this.selector = newSelector;
    logger.warning("Recreated Selector because of possible java/network stack bug.");
}
Also used : SelectionKey(java.nio.channels.SelectionKey) ClosedChannelException(java.nio.channels.ClosedChannelException) SelectableChannel(java.nio.channels.SelectableChannel) CancelledKeyException(java.nio.channels.CancelledKeyException) Selector(java.nio.channels.Selector)

Example 5 with SelectableChannel

use of java.nio.channels.SelectableChannel in project jeromq by zeromq.

the class ZMQ method poll.

/**
     * Polling on items with given selector
     * CAUTION: This could be affected by jdk epoll bug
     *
     * @param selector Open and reuse this selector and do not forget to close when it is not used.
     * @param items
     * @param count
     * @param timeout
     * @return number of events
     */
public static int poll(Selector selector, PollItem[] items, int count, long timeout) {
    if (items == null) {
        throw new IllegalArgumentException();
    }
    if (count == 0) {
        if (timeout <= 0) {
            return 0;
        }
        try {
            Thread.sleep(timeout);
        } catch (InterruptedException e) {
        }
        return 0;
    }
    long now = 0L;
    long end = 0L;
    HashMap<SelectableChannel, SelectionKey> saved = new HashMap<SelectableChannel, SelectionKey>();
    for (SelectionKey key : selector.keys()) {
        if (key.isValid()) {
            saved.put(key.channel(), key);
        }
    }
    for (int i = 0; i < count; i++) {
        PollItem item = items[i];
        if (item == null) {
            continue;
        }
        // mailbox channel if ZMQ socket
        SelectableChannel ch = item.getChannel();
        SelectionKey key = saved.remove(ch);
        if (key != null) {
            if (key.interestOps() != item.interestOps()) {
                key.interestOps(item.interestOps());
            }
            key.attach(item);
        } else {
            try {
                ch.register(selector, item.interestOps(), item);
            } catch (ClosedChannelException e) {
                throw new ZError.IOException(e);
            }
        }
    }
    if (!saved.isEmpty()) {
        for (SelectionKey deprecated : saved.values()) {
            deprecated.cancel();
        }
    }
    boolean firstPass = true;
    int nevents = 0;
    int ready;
    while (true) {
        //  Compute the timeout for the subsequent poll.
        long waitMillis;
        if (firstPass) {
            waitMillis = 0L;
        } else if (timeout < 0L) {
            waitMillis = -1L;
        } else {
            waitMillis = end - now;
        }
        //  Wait for events.
        try {
            int rc = 0;
            if (waitMillis < 0) {
                rc = selector.select(0);
            } else if (waitMillis == 0) {
                rc = selector.selectNow();
            } else {
                rc = selector.select(waitMillis);
            }
            for (SelectionKey key : selector.keys()) {
                PollItem item = (PollItem) key.attachment();
                ready = item.readyOps(key, rc);
                if (ready < 0) {
                    return -1;
                }
                if (ready > 0) {
                    nevents++;
                }
            }
            selector.selectedKeys().clear();
        } catch (IOException e) {
            throw new ZError.IOException(e);
        }
        //  If timeout is zero, exit immediately whether there are events or not.
        if (timeout == 0) {
            break;
        }
        if (nevents > 0) {
            break;
        }
        //  If timeout is infinite we can just loop until we get some events.
        if (timeout < 0) {
            if (firstPass) {
                firstPass = false;
            }
            continue;
        }
        //  when the polling should time out.
        if (firstPass) {
            now = Clock.nowMS();
            end = now + timeout;
            if (now == end) {
                break;
            }
            firstPass = false;
            continue;
        }
        //  Find out whether timeout have expired.
        now = Clock.nowMS();
        if (now >= end) {
            break;
        }
    }
    return nevents;
}
Also used : SelectionKey(java.nio.channels.SelectionKey) ClosedChannelException(java.nio.channels.ClosedChannelException) HashMap(java.util.HashMap) IOException(java.io.IOException) SelectableChannel(java.nio.channels.SelectableChannel)

Aggregations

SelectableChannel (java.nio.channels.SelectableChannel)25 SelectionKey (java.nio.channels.SelectionKey)13 IOException (java.io.IOException)5 Selector (java.nio.channels.Selector)4 SocketChannel (java.nio.channels.SocketChannel)4 Test (org.junit.Test)4 SocketTimeoutException (java.net.SocketTimeoutException)3 CancelledKeyException (java.nio.channels.CancelledKeyException)3 ClosedChannelException (java.nio.channels.ClosedChannelException)3 ServerSocketChannel (java.nio.channels.ServerSocketChannel)3 Socket (org.zeromq.ZMQ.Socket)3 ConnectException (java.net.ConnectException)2 InetSocketAddress (java.net.InetSocketAddress)2 HashMap (java.util.HashMap)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 QueuedThreadPool (org.eclipse.jetty.util.thread.QueuedThreadPool)2 ChannelException (io.netty.channel.ChannelException)1 EventLoopException (io.netty.channel.EventLoopException)1 FileDescriptor (java.io.FileDescriptor)1 Socket (java.net.Socket)1