Bug 572918 - JobManager.beginRule() doesn't block if job has different rule
Summary: JobManager.beginRule() doesn't block if job has different rule
Status: NEW
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Runtime (show other bugs)
Version: 4.15   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: platform-runtime-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-04-16 09:55 EDT by Andrey Loskutov CLA
Modified: 2021-04-16 09:58 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrey Loskutov CLA 2021-04-16 09:55:48 EDT
I've stumbled over the code where we schedule a job with custom rule, and inside the job we are trying to begin a MultuRule that combines job rule and workspace root rule.

The purpose is: the job in question should not block workspace immediately (but should be able to lock workspace/wait on workspace lock inside the job run() method), and should not run in parallel to other job with same custom rule.

So that would be the code:

static class ExclusiveRule implements ISchedulingRule {
    public boolean contains(ISchedulingRule rule) {
        return rule instanceof ExclusiveRule || rule instanceof IWorkspaceRoot;
    }
    public boolean isConflicting(ISchedulingRule rule) {
        return contains(rule);
    }
}

MyJob job = new MyJob();
job.setRule(new ExclusiveRule());

The MyJob.run() looks like:

protected IStatus run(IProgressMonitor monitor) {
// ... some code that doesn't need workspace lock
// ...

    ISchedulingRule rule = MultiRule.combine(getRule(), ResourcesPlugin.getWorkspace().getRoot());

// Now we want lock workspace - and we want to wait if it is already locked
    Job.getJobManager().beginRule(rule, monitor);

The bad thing is: if there is a job running, that has already acquired workspace rule (like AutoBuildJob), the JobManager freely allows us to proceed after beginRule() call and does NOT block.

If we don't set the rule on the job at the beginning, everything works as expected and JobManager.beginRule() blocks if build is running - but then we can't force this job instances to run sequentially. That looks like a bug in ImplicitJobs for me, but I wonder that such "basic" issue was not found before???

Tentative patch (have not validated / run tests yet):

diff --git a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/ImplicitJobs.java b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/ImplicitJobs.java
index dee9357..2d28b24 100644
--- a/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/ImplicitJobs.java
+++ b/bundles/org.eclipse.core.jobs/src/org/eclipse/core/internal/jobs/ImplicitJobs.java
@@ -73,5 +73,10 @@
 			Job realJob = manager.currentJob();
-			if (realJob != null && realJob.getRule() != null)
+			if (realJob != null && realJob.getRule() != null) {
 				threadJob = newThreadJob(realJob.getRule());
-			else {
+				// if current job tries to acquire a rule different to own rule,
+				// we should perform rule check again
+				if (rule != realJob.getRule()) {
+					threadJob.acquireRule = true;
+				}
+			} else {
 				threadJob = newThreadJob(rule);
Comment 1 Eclipse Genie CLA 2021-04-16 09:58:41 EDT
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.runtime/+/179432