public void select()

in proton-j/src/main/java/org/apache/qpid/proton/reactor/impl/SelectorImpl.java [97:179]


    public void select(long timeout) throws IOException {

        long now = System.currentTimeMillis();
        if (timeout > 0) {
            long deadline = 0;
            // XXX: Note: this differs from the C code which requires a call to update() to make deadline changes take affect
            for (Selectable selectable : selectables) {
                long d = selectable.getDeadline();
                if (d > 0) {
                    deadline = (deadline == 0) ? d : Math.min(deadline,  d);
                }
            }

            if (deadline > 0) {
                long delta = deadline - now;
                if (delta < 0) {
                    timeout = 0;
                } else if (delta < timeout) {
                    timeout = delta;
                }
            }
        }

        error.clear();

        long awoken = 0;
        if (timeout > 0) {
            long remainingTimeout = timeout;
            while(remainingTimeout > 0) {
                selector.select(remainingTimeout);
                awoken = System.currentTimeMillis();

                for (Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); iterator.hasNext();) {
                    SelectionKey key = iterator.next();
                    if (key.isConnectable()) {
                        try {
                            ((SocketChannel)key.channel()).finishConnect();
                            update((Selectable)key.attachment());
                        } catch(IOException ioException) {
                            SelectableImpl selectable = (SelectableImpl)key.attachment();
                            ErrorCondition condition = new ErrorCondition();
                            condition.setCondition(Symbol.getSymbol("proton:io"));
                            condition.setDescription(ioException.getMessage());
                            Transport transport = selectable.getTransport();
                            if (transport != null) {
                                transport.setCondition(condition);
                                transport.close_tail();
                                transport.close_head();
                                transport.pop(Math.max(0, transport.pending())); // Force generation of TRANSPORT_HEAD_CLOSE (not in C code)
                            }
                            error.add(selectable);
                        }
                        iterator.remove();
                    }
                }
                if (!selector.selectedKeys().isEmpty()) {
                    break;
                }
                remainingTimeout = remainingTimeout - (awoken - now);
            }
        } else {
            selector.selectNow();
            awoken = System.currentTimeMillis();
        }

        readable.clear();
        writeable.clear();
        expired.clear();
        for (SelectionKey key : selector.selectedKeys()) {
            Selectable selectable = (Selectable)key.attachment();
            if (key.isReadable()) readable.add(selectable);
            if (key.isAcceptable()) readable.add(selectable);
            if (key.isWritable()) writeable.add(selectable);
        }
        selector.selectedKeys().clear();
        // XXX: Note: this is different to the C code which evaluates expiry at the point the selectable is iterated over.
        for (Selectable selectable : selectables) {
            long deadline = selectable.getDeadline();
            if (deadline > 0 && awoken >= deadline) {
                expired.add(selectable);
            }
        }
    }