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