void () { while (!ourIndexingJobs.isEmpty()) { boolean allJobsAreSuspended = true; for (IndexingJob job : ourIndexingJobs) { ProgressIndicator jobIndicator = job.myIndicator; if (job.myProject.isDisposed() || job.myNoMoreFilesInQueue.get() || jobIndicator.isCanceled() || job.myError.get() != null) { ourIndexingJobs.remove(job); allJobsAreSuspended = false; continue; } ProgressSuspender suspender = job.myOriginalProgressSuspender; if (suspender != null && suspender.isSuspended()) { continue; } allJobsAreSuspended = false; try { Runnable work = () -> indexOneFileOfJob(job); if (suspender != null) { // Here it is important to use the original progress indicator which is directly associated with the ProgressSuspender. suspender.executeNonSuspendableSection(job.myOriginalProgressIndicator, work); } else { work.run(); } } catch (Throwable e) { job.myError.compareAndSet(null, e); ourIndexingJobs.remove(job); } if( WRITE_INDEXES_ON_SEPARATE_THREAD){ sleepIfNecessary(); } } if (allJobsAreSuspended) { // To avoid busy-looping. break; } } }