| Summary: | [Jobs] Need a way to get the active rule stack for a given thread | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [Eclipse Project] Platform | Reporter: | Min Idzelis <min123> | ||||
| Component: | Runtime | Assignee: | John Arthorne <john.arthorne> | ||||
| Status: | RESOLVED FIXED | QA Contact: | |||||
| Severity: | enhancement | ||||||
| Priority: | P3 | CC: | boris.gruschko, thatnitind | ||||
| Version: | 3.4.2 | ||||||
| Target Milestone: | 3.6 M6 | ||||||
| Hardware: | PC | ||||||
| OS: | Windows XP | ||||||
| Whiteboard: | |||||||
| Bug Depends on: | |||||||
| Bug Blocks: | 228962, 287096 | ||||||
| Attachments: |
|
||||||
|
Description
Min Idzelis
See related bug 283446 What we really need is an API to get the outermost non-null rule on the rule stack. Right now it is not possible to get the outermost rule, if a thread becomes upgraded to a Job via beginRule(). However, the usage of this API should be marked with a ton of warning signs. Making such an API available calls for trouble because the users will be tempted to develop their own locking strategies. >What we really need is an API to get the outermost non-null rule on the rule
stack.
I'm not sure what "outermost" is on a stack, but a job only has one "active" rule, and that's held in the slot Job.schedulingRule. All other rules in the stack are subsets of that rule as defined by ISchedulingRule#contains, so that rule should be all you need. The problem seems to be that Job.schedulingRule isn't accurate in the case where the job was started with no rule and then acquired one via beginRule.
Just to clarify: "outermost" is what you call "active" in your terminology. Thanks, that's what I thought but it's good to clarify ;) Outermost could also be interpreted as the top of the stack. Maybe I was referring to an implementation detail. ThreadJob in fact has a field called "ruleStack." If all rules acquired must be contained within the outer rule (with the exception of null, which contains all) then I think just the "topmost, non null rule" should be all we need. However, what would be the behavior of the following code? Assume Job is started with no rule, and A.contains(B) Job (rule=null) acquire A acquire B transfer A to Thread-1 Thread-1 acquire B Will Thread-1 be allowed to start? Or would you need some kind of multi-rule transfer mechanism? > Will Thread-1 be allowed to start?
Yes. In this case A.contains(B) must be true because of the nested acquire in the original thread, so similarly the nested acquire will work in the new thread. Again, a thread only ever really "owns" a single rule. By doing so it implicitly owns every rule for which ownedRule.contains(otherRule) is true. All of these "sub-rules" are owned regardless of whether they are in the rule stack. The rule stack is just used to enforce beginRule/endRule pairs being correctly nested.
(In reply to comment #7) Ok, great! Just wanted to also point out bug 283446 mentioned in comment #2. That bug deals with the fact that when a Job doesn't realize when a rule is transferred to it if the transfer happens *after* it already started to wait for it. That is, if Job (rule=null) acquire A (owned by Thread-1) --(start spin-loop waiting for A) Thread-1 transfer A to Job Job doesn't realize that it now has A after the transfer and stays in its spin-loop. Perhaps these two enhancements can be made at the same time? Oops. The reference bug in both cases was wrong. Please refer to bug 283449. Just pinging this to see to request that this be committed to be fixed in Eclipse 3.6. I also want to call attention to bug 287096 which has some soft dependencies on this bug. Several adopters (Oracle/IBM) are hitting issues that can be fixed if this bug is fixed. I have a very preliminary implementation/proposal. This is a partial patch. Should be added to JobManager.java. getThreadJob() just gets the ThreadJob from the ImplicitJob's threadJobs map.
public ISchedulingRule currentRule() {
Thread current = Thread.currentThread();
ISchedulingRule currentRule = null;
synchronized (lock) {
synchronized (implicitJobs) {
ThreadJob job = implicitJobs.getThreadJob(current);
if (job != null) {
for (int i = 0; i < job.ruleStack.length; i++) {
if (job.ruleStack[i] != null) {
currentRule = job.ruleStack[i];
break;
}
}
} else {
Job currentJob = currentJob();
if (currentJob != null) {
currentRule = currentJob.getRule();
}
}
}
}
return currentRule;
}
Created attachment 160651 [details]
API and implementation
I have released this in HEAD, along with test suites in IJobManagerTest. |