("" + (directBufferBytes/1024) + " kB direct buffers."))); for(int i=0; i<numSelectorThreads; ++i) { selectorThreads.add(new SelectorThread(i));
if (!selectorThread.addAcceptedConnection(sc)) { throw new IOException( "Unable to add connection to selector queue"
while (!stopped) { try { select(); processAcceptedConnections(); processInterestOpsUpdateRequests(); } catch (RuntimeException e) { LOG.warn("Ignoring unexpected runtime exception", e); cnxn.close(); cleanupSelectionKey(key); fastCloseSock(accepted); closeSelector();
public void stop() { stopped = true; // Stop queuing connection attempts try { ss.close(); } catch (IOException e) { LOG.warn("Error closing listen socket", e); } if (acceptThread != null) { if (acceptThread.isAlive()) { acceptThread.wakeupSelector(); } else { acceptThread.closeSelector(); } } if (expirerThread != null) { expirerThread.interrupt(); } for (SelectorThread thread : selectorThreads) { if (thread.isAlive()) { thread.wakeupSelector(); } else { thread.closeSelector(); } } if (workerPool != null) { workerPool.stop(); } }
public void doWork() throws InterruptedException { if (!key.isValid()) { selectorThread.cleanupSelectionKey(key); return; } if (key.isReadable() || key.isWritable()) { cnxn.doIO(key); // Check if we shutdown or doIO() closed this connection if (stopped) { cnxn.close(); return; } if (!key.isValid()) { selectorThread.cleanupSelectionKey(key); return; } touchCnxn(cnxn); } // Mark this connection as once again ready for selection cnxn.enableSelectable(); // Push an update request on the queue to resume selecting // on the current set of interest ops, which may have changed // as a result of the I/O operations we just performed. if (!selectorThread.addInterestOpsUpdateRequest(key)) { cnxn.close(); } }
private void select() { try { selector.select(); Set<SelectionKey> selected = selector.selectedKeys(); ArrayList<SelectionKey> selectedList = new ArrayList<SelectionKey>(selected); Collections.shuffle(selectedList); Iterator<SelectionKey> selectedKeys = selectedList.iterator(); while(!stopped && selectedKeys.hasNext()) { SelectionKey key = selectedKeys.next(); selected.remove(key); if (!key.isValid()) { cleanupSelectionKey(key); continue; } if (key.isReadable() || key.isWritable()) { handleIO(key); } else { LOG.warn("Unexpected ops in select " + key.readyOps()); } } } catch (IOException e) { LOG.warn("Ignoring IOException while selecting", e); } }
@Override public void start() { stopped = false; if (workerPool == null) { workerPool = new WorkerService( "NIOWorker", numWorkerThreads, false); } for(SelectorThread thread : selectorThreads) { if (thread.getState() == Thread.State.NEW) { thread.start(); } } // ensure thread is started once and only once if (acceptThread.getState() == Thread.State.NEW) { acceptThread.start(); } if (expirerThread.getState() == Thread.State.NEW) { expirerThread.start(); } }
/** * Iterate over the queue of accepted connections that have been * assigned to this thread but not yet placed on the selector. */ private void processAcceptedConnections() { SocketChannel accepted; while (!stopped && (accepted = acceptedQueue.poll()) != null) { SelectionKey key = null; try { key = accepted.register(selector, SelectionKey.OP_READ); NIOServerCnxn cnxn = createConnection(accepted, key, this); key.attach(cnxn); addCnxn(cnxn); } catch (IOException e) { // register, createConnection cleanupSelectionKey(key); fastCloseSock(accepted); } } }
/** * Iterate over the queue of connections ready to resume selection, * and restore their interest ops selection mask. */ private void processInterestOpsUpdateRequests() { SelectionKey key; while (!stopped && (key = updateQueue.poll()) != null) { if (!key.isValid()) { cleanupSelectionKey(key); } NIOServerCnxn cnxn = (NIOServerCnxn) key.attachment(); if (cnxn.isSelectable()) { key.interestOps(cnxn.getInterestOps()); } } } }
public boolean addInterestOpsUpdateRequest(SelectionKey sk) { return super.addInterestOpsUpdateRequest(sk); } }
@Override public void join() throws InterruptedException { if (acceptThread != null) { acceptThread.join(); } for (SelectorThread thread : selectorThreads) { thread.join(); } if (workerPool != null) { workerPool.join(workerShutdownTimeoutMS); } }
private void requestInterestOpsUpdate() { if (isSelectable()) { selectorThread.addInterestOpsUpdateRequest(sk); } }