New multi-job for processing a queue of jobs
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/jobs/MultiJob.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/jobs/MultiJob.java new file mode 100644 index 0000000..e654cd6 --- /dev/null +++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/jobs/MultiJob.java
@@ -0,0 +1,74 @@ +/********************************************************************** + * Copyright (c) 2003 IBM Corporation and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Common Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.core.runtime.jobs; + +import org.eclipse.core.internal.jobs.Queue; +import org.eclipse.core.runtime.*; + +/** + * A MultiJob processes its own queue of work items until the queue is empty, + * and schedules itself when necessary. This ensures that all work is done in + * a strictly sequential order, and in one thread. + */ +public abstract class MultiJob extends Job { + private Queue queue = new Queue(); + /** + * True when actively processing the work queue or waiting to do so. False + * otherwise (when finished processing the work queue, or when not scheduled). + */ + private boolean working; + private String taskName; + + public MultiJob(String name) { + this.taskName = name == null ? "" : name; //$NON-NLS-1$ + //add a listener to reschedule the job if there is work to do + addJobChangeListener(new JobChangeAdapter() { + public void done(Job job, IStatus result) { + boolean hasWork = false; + synchronized (queue) { + hasWork = queue.isEmpty(); + } + if (hasWork & !working) { + working = true; + schedule(); + } + } + }); + } + public final void addWork(Object work) { + synchronized (queue) { + queue.enqueue(work); + } + if (!working) { + working = true; + schedule(); + } + } + public abstract IStatus doWork(Object work); + public final IStatus run(IProgressMonitor monitor) { + monitor.beginTask(taskName, IProgressMonitor.UNKNOWN); + try { + Object work = null; + while (working) { + synchronized (queue) { + work = queue.dequeue(); + if (work == null) { + working = false; + break; + } + } + doWork(work); + } + } finally { + monitor.done(); + } + return Status.OK_STATUS; + } +} \ No newline at end of file