private boolean acquireSnapshot(long timeoutInMillis, boolean requireChange, boolean isInitializing) {
        boolean applyOnRestartOnly;
        synchronized (monitor) {
            if (state == State.CLOSED) throw new SubscriberClosedException();
            state = State.FROZEN;
            applyOnRestartOnly = applyOnRestart;
        }
        boolean expiredOnEntry = (timeoutInMillis <= 0);
        long started = now(expiredOnEntry);
        long timeLeftMillis = timeoutInMillis;
        boolean anyConfigChanged = false;

        Long currentGen = null;
        for (ConfigHandle<? extends ConfigInstance> h : subscriptionHandles) {
            h.setChanged(false); // Reset this flag, if it was set, the user should have acted on it the last time this method returned true.
        }
        boolean reconfigDue;
        do {
            boolean allGenerationsChanged = true;
            boolean allGenerationsTheSame = true;
            // Keep on polling the subscriptions until we have a new generation across the board, or it times out
            for (ConfigHandle<? extends ConfigInstance> h : subscriptionHandles) {
                ConfigSubscription<? extends ConfigInstance> subscription = h.subscription();
                log.log(Level.FINEST, () -> "Calling nextConfig for " + subscription.getKey());
                if ( ! subscription.nextConfig(timeLeftMillis)) {
                    // This subscriber has no new state, and we know it has exhausted the timeout
                    log.log(Level.FINEST, () -> "No new config for " + subscription.getKey());
                    return false;
                }
                log.log(Level.FINEST, () -> "Got new generation or config for " + subscription.getKey());
                throwIfExceptionSet(subscription);
                ConfigSubscription.ConfigState<? extends ConfigInstance> config = subscription.getConfigState();
                if (currentGen == null) currentGen = config.getGeneration();
                allGenerationsTheSame &= currentGen.equals(config.getGeneration());
                allGenerationsChanged &= config.isGenerationChanged();
                anyConfigChanged      |= config.isConfigChanged();
                applyOnRestartOnly    |= config.applyOnRestart();
                timeLeftMillis = timeoutInMillis + started - now(expiredOnEntry);
            }
            reconfigDue = (isInitializing || !applyOnRestartOnly) && (anyConfigChanged || !requireChange)
                          && allGenerationsChanged && allGenerationsTheSame;

            if (applyOnRestartOnly && ! isInitializing) { // disable any reconfig until restart
                synchronized (monitor) {
                    if ( ! applyOnRestart) {
                        log.log(Level.INFO, "Config generation " + generation + " requires restart; " +
                                            "further config changes will not take effect until restart");
                        applyOnRestart = true;
                    }
                }
            }

            if (!reconfigDue && timeLeftMillis > 0) {
                sleep(timeLeftMillis);
            }
        } while (!reconfigDue && timeLeftMillis > 0);
        if (reconfigDue) {
            // This indicates the clients will possibly reconfigure their services, so "reset" changed-logic in subscriptions.
            // Also if appropriate update the changed flag on the handler, which clients use.
            log.log(Level.FINE, () -> "Reconfig will happen for generation " + generation);
            markSubsChangedSeen(currentGen);
            synchronized (monitor) {
                generation = currentGen;
            }
        }
        return reconfigDue;
    }
Acquire a snapshot of all configs with the same generation within a timeout.

@param timeoutInMillis timeout to wait in milliseconds
@param requireChange if set, at least one config have to change
@return true, if a new config generation has been found for all configs (additionally requires
        that at lest one of them has changed if <code>requireChange</code> is true), and
        the config should be applied at this time, false otherwise
config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java