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);
}
}
}