@Override
  public void run() {
    final AtomicBoolean done = new AtomicBoolean();
    long totalStart = System.nanoTime();

    String[] supportedMechs;
    long mechsStart = System.nanoTime();
    if (authDescriptor.getMechs() == null
      || authDescriptor.getMechs().length == 0) {
      supportedMechs = listSupportedSASLMechanisms(done);
    } else {
      supportedMechs = authDescriptor.getMechs();
    }
    long mechsDiff = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()
      - mechsStart);
    String msg = String.format("SASL List Mechanisms took %dms on %s",
      mechsDiff, node.toString());
    Level level = mechsDiff
      >= AUTH_ROUNDTRIP_THRESHOLD ? Level.WARN : Level.DEBUG;
    getLogger().log(level, msg);

    if (supportedMechs == null || supportedMechs.length == 0) {
      getLogger().warn("Authentication failed to " + node.getSocketAddress()
        + ", got empty SASL auth mech list.");
      throw new IllegalStateException("Got empty SASL auth mech list.");
    }

    OperationStatus priorStatus = null;
    while (!done.get()) {
      long stepStart = System.nanoTime();
      final CountDownLatch latch = new CountDownLatch(1);
      final AtomicReference<OperationStatus> foundStatus =
        new AtomicReference<OperationStatus>();

      final OperationCallback cb = new OperationCallback() {

        @Override
        public void receivedStatus(OperationStatus val) {
          // If the status we found was null, we're done.
          if (val.getMessage().length() == 0) {
            done.set(true);
            node.authComplete();
            getLogger().info("Authenticated to " + node.getSocketAddress());
          } else {
            foundStatus.set(val);
          }
        }

        @Override
        public void complete() {
          latch.countDown();
        }
      };

      // Get the prior status to create the correct operation.
      final Operation op = buildOperation(priorStatus, cb, supportedMechs);
      conn.insertOperation(node, op);

      try {
        if (!conn.isShutDown()) {
          latch.await();
        } else {
          done.set(true); // Connection is shutting down, tear.down.
        }
        Thread.sleep(100);
      } catch (InterruptedException e) {
        // we can be interrupted if we were in the
        // process of auth'ing and the connection is
        // lost or dropped due to bad auth
        Thread.currentThread().interrupt();
        if (op != null) {
          op.cancel();
        }
        done.set(true); // If we were interrupted, tear down.
      } finally {
        long stepDiff = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()
          - stepStart);
        msg = String.format("SASL Step took %dms on %s",
          stepDiff, node.toString());
        level = mechsDiff
          >= AUTH_ROUNDTRIP_THRESHOLD ? Level.WARN : Level.DEBUG;
        getLogger().log(level, msg);
      }

      // Get the new status to inspect it.
      priorStatus = foundStatus.get();
      if (priorStatus != null) {
        if (!priorStatus.isSuccess()) {
          getLogger().warn("Authentication failed to " + node.getSocketAddress()
            + ", Status: " + priorStatus);
        }
      }
    }

    long totalDiff = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()
      - totalStart);
    msg = String.format("SASL Auth took %dms on %s",
      totalDiff, node.toString());
    level = mechsDiff >= AUTH_TOTAL_THRESHOLD ? Level.WARN : Level.DEBUG;
    getLogger().log(level, msg);
  }
If the total AUTH steps take longer than this period in milliseconds, a
warning will be issued instead of a debug message.
src/main/java/net/spy/memcached/auth/AuthThread.java