private void flushAllIndices(final int modCount) {
      if (betterToInterruptFlushingEarly(modCount)) {
        return;
      }

      IndexingStamp.flushCaches();

      final int maxAttemptsPerIndex = 2;
      final int maxSleepPerAttemptMs = 16;

      IndexConfiguration state = getState();
      int interferencesWithOtherThreads = 0;
      for (ID<?, ?> indexId : state.getIndexIDs()) {
        if (betterToInterruptFlushingEarly(modCount)) {
          return; // do not interfere with 'main' jobs
        }
        try {
          final UpdatableIndex<?, ?, FileContent, ?> index = state.getIndex(indexId);
          if (index != null) {
            //RC: regular flush should not interfere with other, (likely) more response-time-critical
            //    jobs. We can't guarantee the total absence of interference, though -- instead we're
            //    trying to be just 'nice to others' here.
            //    I.e. do .yield() after each flush, so somebody who waits for index access -- has its
            //    chance. We also use .tryLock() as a way to feel interference (readLock.tryLock fails
            //    -> somebody else acquired write lock), and back off a bit, giving 'another job' a chance
            //    to finish.
            //    (See e.g., IDEA-244174 for what could go wrong otherwise)

            for (int attempt = 0; attempt < maxAttemptsPerIndex; attempt++) {
              final ReadWriteLock rwLock = index.getLock();
              final Lock indexReadLock = rwLock.readLock();
              final boolean lockSucceeded = indexReadLock.tryLock();
              if (lockSucceeded) {
                try {
                  index.flush();
                }
                finally {
                  indexReadLock.unlock();
                }
                interferencesWithOtherThreads--;
                break;
              }
              else {
                interferencesWithOtherThreads++;
              }

              // linear backoff based on how many times we contended with others:
              final int toWaitMs = clamp(interferencesWithOtherThreads, 0, maxSleepPerAttemptMs);
              if (toWaitMs == 0) {
                Thread.yield();
              }
              else {
                Thread.sleep(toWaitMs);
              }
            }
          }
        }
        catch (Throwable e) {
          requestRebuild(indexId, e);
        }
      }
    }
private void flushAllIndices(final int modCount)