Bug 578867 - report first (non system) job of family to block Change-Id: I609094e0a70ab444bf0b748180f7b47bf958ac84 Signed-off-by: Joerg Kubitz <jkubitz-eclipse@gmx.de> Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.runtime/+/191004 Tested-by: Platform Bot <platform-bot@eclipse.org>
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 90dc5de..011c1f8 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
@@ -946,16 +946,12 @@ IJobChangeListener listener = null; final Set<InternalJob> jobs; int jobCount; - Job blocking = null; synchronized (lock) { //don't join a waiting or sleeping job when suspended (deadlock risk) int states = suspended ? Job.RUNNING : Job.RUNNING | Job.WAITING | Job.SLEEPING; jobs = Collections.synchronizedSet(new HashSet<>(select(family, states))); jobCount = jobs.size(); if (jobCount > 0) { - //if there is only one blocking job, use it in the blockage callback below - if (jobCount == 1) - blocking = (Job) jobs.iterator().next(); listener = new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { @@ -1009,10 +1005,18 @@ try { monitor.beginTask(JobMessages.jobs_blocked0, jobCount); monitor.subTask(getWaitMessage(jobCount)); - reportBlocked(monitor, blocking); int jobsLeft; int reportedWorkDone = 0; + List<InternalJob> reportedBlockingJobs = List.of(); while ((jobsLeft = jobs.size()) > 0) { + List<InternalJob> blockingJobs; + synchronized (jobs) { + blockingJobs = new ArrayList<>(jobs); + } + if (!Objects.equals(reportedBlockingJobs, blockingJobs)) { + reportBlocked(monitor, blockingJobs); + reportedBlockingJobs = blockingJobs; + } //don't let there be negative work done if new jobs have //been added since the join began int actualWorkDone = Math.max(0, jobCount - jobsLeft); @@ -1212,16 +1216,19 @@ } /** - * Report to the progress monitor that this thread is blocked, supplying - * an information message, and if possible the job that is causing the blockage. - * Important: An invocation of this method MUST be followed eventually be - * an invocation of reportUnblocked. - * @param monitor The monitor to report blocking to - * @param blockingJob The job that is blocking this thread, or <code>null</code> + * Report to the progress monitor that this thread is blocked, supplying an + * information message, and if possible jobs that are causing the blockage. + * Important: An invocation of this method MUST be followed eventually be an + * invocation of reportUnblocked. + * + * @param monitor The monitor to report blocking to + * @param blockingJobs The jobs that are blocking this thread * @see #reportUnblocked */ - final void reportBlocked(IProgressMonitor monitor, InternalJob blockingJob) { + final void reportBlocked(IProgressMonitor monitor, List<InternalJob> blockingJobs) { IStatus reason; + InternalJob blockingJob = blockingJobs.stream().sorted(Comparator.comparing(InternalJob::isSystem)).findFirst() + .orElse(null); if (blockingJob == null || blockingJob instanceof ThreadJob || blockingJob.isSystem()) { reason = new Status(IStatus.INFO, JobManager.PI_JOBS, 1, JobMessages.jobs_blocked0, null); } else {
diff --git a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/ThreadJob.java b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/ThreadJob.java index df47189..6ed718f 100644 --- a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/ThreadJob.java +++ b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/ThreadJob.java
@@ -13,6 +13,7 @@ *******************************************************************************/ package org.eclipse.core.internal.jobs; +import java.util.List; import org.eclipse.core.internal.runtime.RuntimeLog; import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.jobs.*; @@ -507,7 +508,7 @@ */ static private void waitStart(ThreadJob threadJob, IProgressMonitor monitor, InternalJob blockingJob) { threadJob.isBlocked = true; - manager.reportBlocked(monitor, blockingJob); + manager.reportBlocked(monitor, blockingJob == null ? List.of() : List.of(blockingJob)); } /**