private InternalDistributedMember waitForPrimaryMember(long timeout) {
    synchronized (this) {
      // let's park this thread and wait for a primary!
      StopWatch timer = new StopWatch(true);
      long warnTime = getDistributionManager().getConfig().getAckWaitThreshold() * 1000L;
      boolean loggedWarning = false;
      try {
        for (;;) {
          // bail out if the system starts closing
          getAdvisee().getCancelCriterion().checkCancelInProgress(null);
          final InternalCache cache = getBucket().getCache();
          if (cache != null && cache.isCacheAtShutdownAll()) {
            throw cache.getCacheClosedException("Cache is shutting down");
          }

          if (getBucketRedundancy() == -1) {
            // there are no real buckets in other vms... no reason to wait
            return null;
          }
          getProxyBucketRegion().getPartitionedRegion().checkReadiness();
          if (isClosed()) {
            break;
          }
          long elapsed = timer.elapsedTimeMillis();
          long timeLeft = timeout - elapsed;
          if (timeLeft <= 0) {
            break;
          }
          if (getBucketRedundancy() == -1 || isClosed()) {
            break; // early out... all bucket regions are gone or we closed
          }
          InternalDistributedMember primary = basicGetPrimaryMember();
          if (primary != null) {
            return primary;
          }

          if (logger.isDebugEnabled()) {
            logger.debug("Waiting for bucket {}. Time left :{} ms", this, timeLeft);
          }

          // Log a warning if we have waited for the ack wait threshold time.
          if (!loggedWarning) {
            long timeUntilWarning = warnTime - elapsed;
            if (timeUntilWarning <= 0) {
              logger
                  .warn(
                      "{} secs have elapsed waiting for a primary for bucket {}. Current bucket owners {}",
                      new Object[] {warnTime / 1000L, this, adviseInitialized()});
              // log a warning;
              loggedWarning = true;
            } else {
              timeLeft = timeLeft > timeUntilWarning ? timeUntilWarning : timeLeft;
            }
          }
          wait(timeLeft); // spurious wakeup ok
        }
      } catch (InterruptedException e) {
        // abort and return null
        Thread.currentThread().interrupt();
      } finally {
        if (loggedWarning) {
          logger.info(
              "Wait for primary completed");
        }
      }
      return null;
    }
  }
Wait briefly for a primary member to be identified.

@param timeout time in milliseconds to wait for a primary
@return the primary bucket host
geode-core/src/main/java/org/apache/geode/internal/cache/BucketAdvisor.java