diff --git a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobManager.java b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobManager.java
index 9c6ec9abc..debdc2277 100644
--- a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobManager.java
+++ b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/JobManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2020 IBM Corporation and others.
+ * Copyright (c) 2003, 2022 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -20,7 +20,8 @@
* Jan Koehnlein - Fix for bug 60964 (454698)
* Terry Parker - Bug 457504, Publish a job group's final status to IJobChangeListeners
* Xored Software Inc - Fix for bug 550738
- * Christoph Laeubrich - remove deprecated API
+ * Christoph Laeubrich - remove deprecated API
+ * - Issue #40 - UI freezes when a ThreadJob is waiting to run in the UI Thread
*******************************************************************************/
package org.eclipse.core.internal.jobs;
@@ -1100,19 +1101,27 @@ boolean join(InternalJobGroup jobGroup, long timeout, IProgressMonitor monitor)
}
/**
- * Returns a non-null progress monitor instance. If the monitor is null,
- * returns the default monitor supplied by the progress provider, or a
- * NullProgressMonitor if no default monitor is available.
+ * Returns a non-null progress monitor instance. If a progress provider is set,
+ * it is asked to provide a wrapped instance of the given monitor
+ * parameter. If no progress provider is set and monitor
is null, a
+ * NullProgressMonitor is returned in all other cases the given
+ * monitor
instance.
+ *
+ * @param monitor the monitor instance (could be null) for further usage
+ * @return a non-null progress monitor instance.
*/
private IProgressMonitor monitorFor(IProgressMonitor monitor) {
- if (monitor == null || (monitor instanceof NullProgressMonitor)) {
- if (progressProvider != null) {
- try {
- monitor = progressProvider.getDefaultMonitor();
- } catch (Exception e) {
- String msg = NLS.bind(JobMessages.meta_pluginProblems, JobManager.PI_JOBS);
- RuntimeLog.log(new Status(IStatus.ERROR, JobManager.PI_JOBS, JobManager.PLUGIN_ERROR, msg, e));
+ if (progressProvider != null) {
+ try {
+ IProgressMonitor monitorFor = progressProvider.monitorFor(monitor);
+ if (monitorFor == null) {
+ throw new IllegalStateException("Internal error: " + //$NON-NLS-1$
+ progressProvider.getClass().getName() + "#monitorFor(" + monitor + ") returned null!"); //$NON-NLS-1$ //$NON-NLS-2$
}
+ return monitorFor;
+ } catch (Exception e) {
+ String msg = NLS.bind(JobMessages.meta_pluginProblems, JobManager.PI_JOBS);
+ RuntimeLog.log(new Status(IStatus.ERROR, JobManager.PI_JOBS, JobManager.PLUGIN_ERROR, msg, e));
}
}
diff --git a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/runtime/jobs/ProgressProvider.java b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/runtime/jobs/ProgressProvider.java
index a2239cef3..c572619f0 100644
--- a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/runtime/jobs/ProgressProvider.java
+++ b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/runtime/jobs/ProgressProvider.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2012 IBM Corporation and others.
+ * Copyright (c) 2003, 2022 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Christoph Läubrich - Issue #40 - UI freezes when a ThreadJob is waiting to run in the UI Thread
*******************************************************************************/
package org.eclipse.core.runtime.jobs;
@@ -96,4 +97,28 @@ public IProgressMonitor createMonitor(Job job, IProgressMonitor group, int ticks
public IProgressMonitor getDefaultMonitor() {
return new NullProgressMonitor();
}
+
+ /**
+ * Returns a (possibly wrapped) progress monitor to use when running in a job.
+ *
+ * The default implementation does the following: + *
monitor
is null or an instance of
+ * {@link NullProgressMonitor} returns the value from a call to
+ * ProgressProvider#getDefaultMonitor()monitor
passed to this
+ * method.
+ * monitor
but never
+ * null
+ * @since 3.13
+ */
+ public IProgressMonitor monitorFor(IProgressMonitor monitor) {
+ if (monitor == null || monitor instanceof NullProgressMonitor) {
+ return getDefaultMonitor();
+ }
+ return monitor;
+ }
}
diff --git a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/BeginEndRuleTest.java b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/BeginEndRuleTest.java
index d1f599449..b9dd6b784 100644
--- a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/BeginEndRuleTest.java
+++ b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/jobs/BeginEndRuleTest.java
@@ -13,11 +13,12 @@
*******************************************************************************/
package org.eclipse.core.tests.runtime.jobs;
-import java.util.concurrent.atomic.AtomicIntegerArray;
+import java.util.concurrent.atomic.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.*;
import org.eclipse.core.tests.harness.FussyProgressMonitor;
import org.eclipse.core.tests.harness.TestBarrier2;
+import org.junit.Test;
/**
* Tests API methods IJobManager.beginRule and IJobManager.endRule
@@ -50,6 +51,39 @@ public void run() {
}
}
+ @Test
+ public void testRuleCallsProgressProvider_monitorFor() {
+ AtomicBoolean createdMonitor = new AtomicBoolean();
+ AtomicReference