void (@NotNull VfsEventsMerger.VfsEventProcessor processor) { ApplicationManager.getApplication().assertReadAccessAllowed(); int publishedEventIndex = getEventMerger().getPublishedEventIndex(); int processedEventIndex = myProcessedEventIndex.get(); if (processedEventIndex == publishedEventIndex) { return; } myWorkersFinishedSync.register(); int phase = myWorkersFinishedSync.getPhase(); try { myFileBasedIndex.waitUntilIndicesAreInitialized(); getEventMerger().processChanges(new VfsEventsMerger.VfsEventProcessor() { @Override public boolean process(VfsEventsMerger.@NotNull ChangeInfo changeInfo) { return ConcurrencyUtil.withLock(myFileBasedIndex.myWriteLock, () -> { try { ProgressManager.getInstance().executeNonCancelableSection(() -> { processor.process(changeInfo); }); } finally { IndexingStamp.flushCache(changeInfo.getFileId()); } return true; }); } @Override public void endBatch() { ConcurrencyUtil.withLock(myFileBasedIndex.myWriteLock, () -> { processor.endBatch(); }); } }); } finally { myWorkersFinishedSync.arriveAndDeregister(); } try { awaitWithCheckCancelled(myWorkersFinishedSync, phase); } catch (RejectedExecutionException | InterruptedException e) { LOG.warn(e); throw new ProcessCanceledException(e); } if (getEventMerger().getPublishedEventIndex() == publishedEventIndex) { myProcessedEventIndex.compareAndSet(processedEventIndex, publishedEventIndex); } }