mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

matthew_swift
05.04.2009 9dc10dec2d5d7f61116f7f647b7cf9596ca77be0
opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java
@@ -57,6 +57,9 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
@@ -66,6 +69,7 @@
import org.opends.server.api.AlertGenerator;
import org.opends.server.api.ClientConnection;
import org.opends.server.api.ConnectionHandler;
import org.opends.server.api.DirectoryThread;
import org.opends.server.api.KeyManagerProvider;
import org.opends.server.api.ServerShutdownListener;
import org.opends.server.api.TrustManagerProvider;
@@ -112,6 +116,34 @@
    ServerShutdownListener, AlertGenerator {
  /**
   * Task run periodically by the connection finalizer.
   */
  private final class ConnectionFinalizerRunnable implements Runnable
  {
    public void run()
    {
      if (!connectionFinalizerActiveJobQueue.isEmpty())
      {
        for (Runnable r : connectionFinalizerActiveJobQueue)
        {
          r.run();
        }
        connectionFinalizerActiveJobQueue.clear();
      }
      // Switch the lists.
      synchronized (connectionFinalizerLock)
      {
        List<Runnable> tmp = connectionFinalizerActiveJobQueue;
        connectionFinalizerActiveJobQueue =
            connectionFinalizerPendingJobQueue;
        connectionFinalizerPendingJobQueue = tmp;
      }
    }
  }
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
@@ -209,7 +241,7 @@
  // The condition variable that will be used by the start method
  // to wait for the socket port to be opened and ready to process
  // requests before returning.
  private Object waitListen = new Object();
  private final Object waitListen = new Object();
  // The friendly name of this connection handler.
  private String friendlyName;
@@ -222,6 +254,19 @@
  private boolean sslConfig = false;
  /**
   * Connection finalizer thread.
   * <p>
   * This thread is defers closing clients for approximately 100ms. This
   * gives the client a chance to close the connection themselves before
   * the server thus avoiding leaving the server side in the TIME WAIT
   * state.
   */
  private final Object connectionFinalizerLock = new Object();
  private ScheduledExecutorService connectionFinalizer;
  private List<Runnable> connectionFinalizerActiveJobQueue;
  private List<Runnable> connectionFinalizerPendingJobQueue;
  /**
   * Creates a new instance of this LDAP connection handler. It must
   * be initialized before it may be used.
   */
@@ -343,25 +388,10 @@
  /**
   * Closes this connection handler so that it will no longer accept
   * new client connections. It may or may not disconnect existing
   * client connections based on the provided flag. Note, however,
   * that some connection handler implementations may not have any way
   * to continue processing requests from existing connections, in
   * which case they should always be closed regardless of the value
   * of the <CODE>closeConnections</CODE> flag.
   *
   * @param finalizeReason
   *          The reason that this connection handler should be
   *          finalized.
   * @param closeConnections
   *          Indicates whether any established client connections
   *          associated with the connection handler should also be
   *          closed.
   * {@inheritDoc}
   */
  @Override
  public void finalizeConnectionHandler(Message finalizeReason,
      boolean closeConnections) {
  public void finalizeConnectionHandler(Message finalizeReason) {
    shutdownRequested = true;
    currentConfig.removeLDAPChangeListener(this);
@@ -390,14 +420,21 @@
      }
    }
    if (closeConnections) {
      for (LDAPRequestHandler requestHandler : requestHandlers) {
        requestHandler.processServerShutdown(finalizeReason);
      }
    } else {
      for (LDAPRequestHandler requestHandler : requestHandlers) {
        requestHandler.registerShutdownListener();
      }
    for (LDAPRequestHandler requestHandler : requestHandlers)
    {
      requestHandler.processServerShutdown(finalizeReason);
    }
    // Shutdown the connection finalizer and ensure that any pending
    // unclosed connections are closed.
    synchronized (connectionFinalizerLock)
    {
      connectionFinalizer.shutdown();
      connectionFinalizer = null;
      Runnable r = new ConnectionFinalizerRunnable();
      r.run(); // Flush active queue.
      r.run(); // Flush pending queue.
    }
  }
@@ -694,6 +731,21 @@
    // listening to. This information can be displayed with jinfo.
    System.setProperty(protocol + "_port", String.valueOf(listenPort));
    // Create and start a connection finalizer thread for this
    // connection handler.
    connectionFinalizer =
        Executors
            .newSingleThreadScheduledExecutor(new DirectoryThread.Factory(
                "LDAP Connection Finalizer for connection handler "
                    + toString()));
    connectionFinalizerActiveJobQueue = new ArrayList<Runnable>();
    connectionFinalizerPendingJobQueue = new ArrayList<Runnable>();
    connectionFinalizer.scheduleWithFixedDelay(
        new ConnectionFinalizerRunnable(), 100, 100,
        TimeUnit.MILLISECONDS);
    // Create and start the request handlers.
    requestHandlers = new LDAPRequestHandler[numRequestHandlers];
    for (int i = 0; i < numRequestHandlers; i++) {
@@ -1257,10 +1309,9 @@
      ResultCode resCode = DirectoryServer.getServerErrorResultCode();
      try {
          String alias = config.getSSLCertNickname();
          if(config.isUseSSL())
              protocol += "+SSL";
          else if(config.isAllowStartTLS())
              protocol += "+TLS";
          if (config.isUseSSL()) {
            protocol = "LDAPS";
          }
          DN keyMgrDN = config.getKeyManagerProviderDN();
          DN trustMgrDN = config.getTrustManagerProviderDN();
          KeyManagerProvider<?> keyManagerProvider =
@@ -1301,4 +1352,27 @@
      }
  }
  /**
   * Enqueue a connection finalizer which will be invoked after a short delay.
   *
   * @param r The connection finalizer runnable.
   */
  void registerConnectionFinalizer(Runnable r)
  {
    synchronized (connectionFinalizerLock)
    {
      if (connectionFinalizer != null)
      {
        connectionFinalizerPendingJobQueue.add(r);
      }
      else
      {
        // Already finalized - invoked immediately.
        r.run();
      }
    }
  }
}