private void processPending() { PendingKey k; while (!pending.isEmpty()) { k = pending.poll(); if (k.Op == PendingKey.OP_WRITE) { if (k.key.isValid()) { k.key.interestOps(SelectionKey.OP_WRITE); } } else if (k.Op == PendingKey.OP_HANDSHAKE) { sslHandshake(k.key); } else { clientClose(k.key); } } }
protected void closeConnections() { if (selector.isOpen()) { boolean cmex; do { cmex = false; try{ for (SelectionKey k : selector.keys()) { if (k != null) clientClose(k); } } catch(java.util.ConcurrentModificationException ex) { cmex = true; } } while(cmex); try { selector.close(); } catch (IOException ignore) { } } }
private void doRead(final SelectionKey key) { SocketChannel ch = (SocketChannel) key.channel(); BufHandler bufHandler = atta(key).getInput(); try { buffer.clear(); // clear for read int read = ch.read(buffer); if (read == -1) { // remote entity shut the socket down cleanly. clientClose(key); } else if (read > 0) { buffer.flip(); // flip for read bufHandler.submit(key, false, buffer); } } catch (IOException e) { // the remote forcibly closed the connection clientClose(key); } }
private void doWrite(SelectionKey key) { NetCtx atta = (NetCtx) key.attachment(); SocketChannel ch = (SocketChannel) key.channel(); try { // the sync is per socket (per client). virtually, no contention // 1. keep byte data order, 2. ensure visibility synchronized (atta) { if (atta.peekWrite() == NetCtx.CLOSE) { clientClose(key); } else if (atta.hasWrites()) { ByteBuffer[] bufs = atta.peekWrites(); ch.write(bufs, 0, bufs.length); // TODO handle CLOSE marks here ... if (atta.cleanWrites()) { key.interestOps(SelectionKey.OP_READ); } } } } catch (IOException e) { // the remote forcibly closed the connection clientClose(key); } }
case BUFFER_OVERFLOW: log.error("at sslEncode(), BUFFER_OVERFLOW should not happen"); clientClose(key); tctx.setSslState(ERROR); break; case BUFFER_UNDERFLOW: log.error("at sslEncode(), BUFFER_UNDERFLOW should not happen"); clientClose(key); tctx.setSslState(ERROR); break; case CLOSED: clientClose(key); tctx.setSslState(CLOSED); break; default: log.error("at sslEncode(), illegal status:" + result.getStatus()); clientClose(key); tctx.setSslState(ERROR); break; clientClose(key); tctx.setSslState(ERROR);
case BUFFER_OVERFLOW: log.error("at sslDataRead: BUFFER_OVERFLOW should not happen"); clientClose(key); tctx.setSslState(ERROR); return; return; case CLOSED: clientClose(key); tctx.setSslState(CLOSED); break; default: log.error("illegal state: " + result.getStatus()); clientClose(key); tctx.setSslState(ERROR); return; log.trace("sslDataRead(): end-of-stream key=" + key); clientClose(key); clientClose(key);
break; default: clientClose(key); break; default: clientClose(key);
clientClose(key); tctx.setSslState(CLOSED); log.traceNio(key, "sslHandshake()->unwrap()", "CLOSED"); } catch (IOException e) { log.error("at sslHandshake", e); clientClose(key); tctx.setSslState(ERROR); log.traceNio(key, "sslHandshake()->unwrap()", "ERROR"); if (engine.isOutboundDone()) { log.error("SSL engine unexpectedly closed."); clientClose(key); tctx.setSslState(ERROR); return; clientClose(key); case BUFFER_UNDERFLOW: log.error("at sslHandshake, BUFFER_UNDERFLOW or BUFFER_OVERFLOW should not happen at write"); clientClose(key); tctx.setSslState(ERROR); return; default: log.error("Invalid SSL status: " + result.getStatus()); clientClose(key); tctx.setSslState(ERROR); return;