/** Infinite loop performing resource indexing */ public void run() { long idlingStart = -1; activateProcessing(); try { class ProgressJob extends Job { ProgressJob(String name) { super(name); } protected IStatus run(IProgressMonitor monitor) { IJob job = currentJob(); while (!monitor.isCanceled() && job != null) { String taskName = new StringBuffer(Messages.jobmanager_indexing) .append( Messages.bind( Messages.jobmanager_filesToIndex, job.getJobFamily(), Integer.toString(awaitingJobsCount()))) .toString(); monitor.subTask(taskName); setName(taskName); try { Thread.sleep(500); } catch (InterruptedException e) { // ignore } job = currentJob(); } return Status.OK_STATUS; } } this.progressJob = null; while (this.processingThread != null) { try { IJob job; synchronized (this) { // handle shutdown case when notifyAll came before the wait but after the while loop was // entered if (this.processingThread == null) continue; // must check for new job inside this sync block to avoid timing hole if ((job = currentJob()) == null) { if (this.progressJob != null) { this.progressJob.cancel(); this.progressJob = null; } if (idlingStart < 0) idlingStart = System.currentTimeMillis(); else notifyIdle(System.currentTimeMillis() - idlingStart); this.wait(); // wait until a new job is posted (or reenabled:38901) } else { idlingStart = -1; } } if (job == null) { notifyIdle(System.currentTimeMillis() - idlingStart); // just woke up, delay before processing any new jobs, allow some time for the active // thread to finish Thread.sleep(500); continue; } if (VERBOSE) { Util.verbose(awaitingJobsCount() + " awaiting jobs"); // $NON-NLS-1$ Util.verbose("STARTING background job - " + job); // $NON-NLS-1$ } try { this.executing = true; if (this.progressJob == null) { this.progressJob = new ProgressJob( Messages.bind( Messages.jobmanager_indexing, "", "")); // $NON-NLS-1$ //$NON-NLS-2$ this.progressJob.setPriority(Job.LONG); this.progressJob.setSystem(true); this.progressJob.schedule(); } /*boolean status = */ job.execute(null); // if (status == FAILED) request(job); } finally { this.executing = false; if (VERBOSE) Util.verbose("FINISHED background job - " + job); // $NON-NLS-1$ moveToNextJob(); if (this.awaitingClients == 0) Thread.sleep(50); } } catch (InterruptedException e) { // background indexing was interrupted } } } catch (RuntimeException e) { if (this.processingThread != null) { // if not shutting down // log exception Util.log(e, "Background Indexer Crash Recovery"); // $NON-NLS-1$ // keep job manager alive discardJobs(null); this.processingThread = null; reset(); // this will fork a new thread with no waiting jobs, some indexes will be // inconsistent } throw e; } catch (Error e) { if (this.processingThread != null && !(e instanceof ThreadDeath)) { // log exception Util.log(e, "Background Indexer Crash Recovery"); // $NON-NLS-1$ // keep job manager alive discardJobs(null); this.processingThread = null; reset(); // this will fork a new thread with no waiting jobs, some indexes will be // inconsistent } throw e; } }