Пример #1
0
  /** 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;
    }
  }