@Override
 public void shutdown(boolean fromShutdownHook) {
   stateGuard.writeLock().lock();
   try {
     state = state.shutdown();
     gcTimer.cancel();
     lockLeaseTimer.cancel();
     remoteLockManager.shutdown();
     runningCondition.signalAll();
     LockStateNode.shutdown();
   } finally {
     stateGuard.writeLock().unlock();
   }
 }
  @Override
  public void recall(
      SessionID session, LockID lock, ServerLockLevel level, int lease, boolean batch) {
    this.stateGuard.readLock().lock();
    try {
      if (isShutdown() || (!sessionManager.isCurrentSession(session))) {
        this.logger.warn(
            "Ignoring recall request from a dead server :"
                + session
                + ", "
                + this.sessionManager
                + " : "
                + lock
                + ", interestedLevel : "
                + level
                + " state: "
                + state);
        return;
      }

      final ClientLock lockState = getClientLockState(lock);
      if (lockState != null) {
        if (lockState.recall(this.remoteLockManager, level, lease, batch)) {
          // schedule the greedy lease
          lockLeaseTimer.schedule(
              new LeaseTask(session, lock, level, batch), lease, TimeUnit.MILLISECONDS);
        }
      }
    } finally {
      this.stateGuard.readLock().unlock();
    }
  }