/** * Operates in a loop, accepting new connections and ensuring that requests on those connections * are handled properly. */ @Override public void run() { setName(handlerName); boolean listening = false; boolean starting = true; while (!shutdownRequested) { // If this connection handler is not enabled, then just sleep // for a bit and check again. if (!enabled) { if (listening) { cleanUpSelector(); listening = false; logger.info(NOTE_CONNHANDLER_STOPPED_LISTENING, handlerName); } if (starting) { // This may happen if there was an initialisation error // which led to disable the connector. // The main thread is waiting for the connector to listen // on its port, which will not occur yet, // so notify here to allow the server startup to complete. synchronized (waitListen) { starting = false; waitListen.notify(); } } StaticUtils.sleep(1000); continue; } // If we have gotten here, then we are about to start listening // for the first time since startup or since we were previously // disabled. Make sure to start with a clean selector and then // create all the listeners. try { cleanUpSelector(); int numRegistered = registerChannels(); // At this point, the connection Handler either started // correctly or failed to start but the start process // should be notified and resume its work in any cases. synchronized (waitListen) { waitListen.notify(); } // If none of the listeners were created successfully, then // consider the connection handler disabled and require // administrative action before trying again. if (numRegistered == 0) { logger.error(ERR_LDAP_CONNHANDLER_NO_ACCEPTORS, currentConfig.dn()); enabled = false; continue; } listening = true; // Enter a loop, waiting for new connections to arrive and // then accepting them as they come in. boolean lastIterationFailed = false; while (enabled && !shutdownRequested) { try { serveIncomingConnections(); lastIterationFailed = false; } catch (Exception e) { logger.traceException(e); logger.error( ERR_CONNHANDLER_CANNOT_ACCEPT_CONNECTION, friendlyName, currentConfig.dn(), getExceptionMessage(e)); if (lastIterationFailed) { // The last time through the accept loop we also // encountered a failure. Rather than enter a potential // infinite loop of failures, disable this acceptor and // log an error. LocalizableMessage message = ERR_CONNHANDLER_CONSECUTIVE_ACCEPT_FAILURES.get( friendlyName, currentConfig.dn(), stackTraceToSingleLineString(e)); logger.error(message); DirectoryServer.sendAlertNotification( this, ALERT_TYPE_LDAP_CONNECTION_HANDLER_CONSECUTIVE_FAILURES, message); cleanUpSelector(); enabled = false; } else { lastIterationFailed = true; } } } if (shutdownRequested) { cleanUpSelector(); selector.close(); listening = false; enabled = false; } } catch (Exception e) { logger.traceException(e); // This is very bad because we failed outside the loop. The // only thing we can do here is log a message, send an alert, // and disable the selector until an administrator can figure // out what's going on. LocalizableMessage message = ERR_LDAP_CONNHANDLER_UNCAUGHT_ERROR.get( currentConfig.dn(), stackTraceToSingleLineString(e)); logger.error(message); DirectoryServer.sendAlertNotification( this, ALERT_TYPE_LDAP_CONNECTION_HANDLER_UNCAUGHT_ERROR, message); cleanUpSelector(); enabled = false; } } }