/** * Add a {@link SelectorHandler} * * @param selectorHandler - the {@link SelectorHandler} */ public void addSelectorHandler(SelectorHandler selectorHandler) { selectorHandlers.add(selectorHandler); if (stateHolder.getState(false) != null && !State.STOPPED.equals(stateHolder.getState())) { addSelectorHandlerOnReadControllers(selectorHandler); if (readySelectorHandlerCounter != null) { readySelectorHandlerCounter.incrementAndGet(); } if (stoppedSelectorHandlerCounter != null) { stoppedSelectorHandlerCounter.incrementAndGet(); } startSelectorHandlerRunner(selectorHandler, true); } }
/** * This method initializes this Controller's default thread pool, default * ProtocolChainInstanceHandler, default SelectorHandler(s) and default ConnectorHandlerPool. * These defaults can be overridden after this Controller constructor is called and before calling * Controller.start() using this Controller's mutator methods to set a different thread pool, * ProtocolChainInstanceHandler, SelectorHandler(s) or ConnectorHandlerPool. */ private void initializeDefaults() { if (threadPool == null) { threadPool = new DefaultThreadPool(); } if (instanceHandler == null) { instanceHandler = new DefaultProtocolChainInstanceHandler(); } if (selectorHandlers == null) { selectorHandlers = new LinkedTransferQueue<SelectorHandler>(); } if (connectorHandlerPool == null) { connectorHandlerPool = new DefaultConnectorHandlerPool(this); } controllers.add(this); }
/** * Start the Controller. If the thread pool and/or Handler has not been defined, the default will * be used. */ public void start() throws IOException { stateHolder.getStateLocker().writeLock().lock(); boolean isUnlocked = false; try { if (stateHolder.getState(false) == null || stateHolder.getState(false) == State.STOPPED) { // if selectorHandlers were not set by user explicitly, // add TCPSelectorHandler by default if (selectorHandlers.isEmpty()) { SelectorHandler selectorHandler = new TCPSelectorHandler(); selectorHandlers.add(selectorHandler); } if (readThreadsCount > 0) { initReadThreads(); multiReadThreadSelectorHandler = new RoundRobinSelectorHandler(readThreadControllers); } stateHolder.setState(State.STARTED, false); notifyStarted(); int selectorHandlerCount = selectorHandlers.size(); readySelectorHandlerCounter = new AtomicInteger(selectorHandlerCount); stoppedSelectorHandlerCounter = new AtomicInteger(selectorHandlerCount); Iterator<SelectorHandler> it = selectorHandlers.iterator(); if (selectorHandlerCount > 1) { for (; it.hasNext() && selectorHandlerCount-- > 0; ) { SelectorHandler selectorHandler = it.next(); startSelectorHandlerRunner(selectorHandler, true); } } else if (it.hasNext()) { SelectorHandler selectorHandler = it.next(); stateHolder.getStateLocker().writeLock().unlock(); isUnlocked = true; startSelectorHandlerRunner(selectorHandler, false); } } } finally { if (!isUnlocked) { stateHolder.getStateLocker().writeLock().unlock(); } } waitUntilSeletorHandlersStop(); if (readThreadsCount > 0) { multiReadThreadSelectorHandler.shutdown(); multiReadThreadSelectorHandler = null; for (Controller readController : readThreadControllers) { try { readController.stop(); } catch (IOException e) { logger.log(Level.WARNING, "Exception occured when stopping read Controller!", e); } } readThreadControllers = null; } selectorHandlers.clear(); threadPool.shutdown(); attributes = null; // Notify Controller listeners for (ControllerStateListener stateListener : stateListeners) { stateListener.onStopped(); } }