Community
Participate
Working Groups
build I20050222-0821 - opened existing workspace - did a search - opened a CU from the matches - noticed the following in the log !ENTRY org.eclipse.ui 4 4 2005-02-25 09:44:04.439 !MESSAGE Attempted to beginRule: R/, does not match outer scope rule: org.eclipse.ui.internal.decorators.DecorationScheduler$1@f55e8c !STACK 0 java.lang.IllegalArgumentException: Attempted to beginRule: R/, does not match outer scope rule: org.eclipse.ui.internal.decorators.DecorationScheduler$1@f55e8c at org.eclipse.core.internal.runtime.Assert.isLegal(Assert.java:58) at org.eclipse.core.internal.jobs.ThreadJob.illegalPush(ThreadJob.java:107) at org.eclipse.core.internal.jobs.ThreadJob.push(ThreadJob.java:201) at org.eclipse.core.internal.jobs.ImplicitJobs.begin(ImplicitJobs.java:81) at org.eclipse.core.internal.jobs.JobManager.beginRule(JobManager.java:186) at org.eclipse.core.internal.resources.WorkManager.checkIn(WorkManager.java:96) at org.eclipse.core.internal.resources.Workspace.prepareOperation(Workspace.java:1657) at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1697) at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:766) at org.eclipse.jdt.internal.core.JavaProject.setRawClasspath(JavaProject.java:2739) at org.eclipse.jdt.core.JavaCore$3.run(JavaCore.java:4004) at org.eclipse.jdt.internal.core.BatchOperation.executeOperation(BatchOperation.java:34) at org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:710) at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1702) at org.eclipse.jdt.core.JavaCore.run(JavaCore.java:3817) at org.eclipse.jdt.core.JavaCore.setClasspathContainer(JavaCore.java:3987) at org.eclipse.pde.internal.core.ModelEntry.updateClasspathContainer(ModelEntry.java:110) at org.eclipse.pde.internal.core.RequiredPluginsInitializer.initialize(RequiredPluginsInitializer.java:40) at org.eclipse.jdt.internal.core.JavaModelManager.initializeContainer(JavaModelManager.java:1274) at org.eclipse.jdt.internal.core.JavaModelManager.getClasspathContainer(JavaModelManager.java:848) at org.eclipse.jdt.core.JavaCore.getClasspathContainer(JavaCore.java:1280) at org.eclipse.jdt.internal.core.search.JavaSearchScope.add(JavaSearchScope.java:134) at org.eclipse.jdt.internal.core.search.JavaWorkspaceScope.initialize(JavaWorkspaceScope.java:80) at org.eclipse.jdt.internal.core.search.JavaSearchScope.<init>(JavaSearchScope.java:56) at org.eclipse.jdt.internal.core.search.JavaWorkspaceScope.<init>(JavaWorkspaceScope.java:31) at org.eclipse.jdt.internal.core.search.BasicSearchEngine.createWorkspaceScope(BasicSearchEngine.java:147) at org.eclipse.jdt.core.search.SearchEngine.createWorkspaceScope(SearchEngine.java:372) at org.eclipse.jdt.internal.core.BinaryType.newSupertypeHierarchy(BinaryType.java:758) at org.eclipse.jdt.internal.core.BinaryType.newSupertypeHierarchy(BinaryType.java:711) at org.eclipse.jdt.internal.corext.util.SuperTypeHierarchyCache.getTypeHierarchy(SuperTypeHierarchyCache.java:88) at org.eclipse.jdt.internal.corext.util.SuperTypeHierarchyCache.getTypeHierarchy(SuperTypeHierarchyCache.java:78) at org.eclipse.jdt.ui.OverrideIndicatorLabelDecorator.getOverrideIndicators(OverrideIndicatorLabelDecorator.java:160) at org.eclipse.jdt.ui.OverrideIndicatorLabelDecorator.computeAdornmentFlags(OverrideIndicatorLabelDecorator.java:128) at org.eclipse.jdt.ui.OverrideIndicatorLabelDecorator.decorate(OverrideIndicatorLabelDecorator.java:239) at org.eclipse.ui.internal.decorators.LightweightDecoratorDefinition.decorate(LightweightDecoratorDefinition.java:220) at org.eclipse.ui.internal.decorators.LightweightDecoratorManager$LightweightRunnable.run(LightweightDecoratorManager.java:65) at org.eclipse.core.internal.runtime.InternalPlatform.run(InternalPlatform.java:1015) at org.eclipse.core.runtime.Platform.run(Platform.java:757) at org.eclipse.ui.internal.decorators.LightweightDecoratorManager.decorate(LightweightDecoratorManager.java:287) at org.eclipse.ui.internal.decorators.LightweightDecoratorManager.getDecorations(LightweightDecoratorManager.java:273) at org.eclipse.ui.internal.decorators.DecorationScheduler$2.run(DecorationScheduler.java:317) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:67)
The steps above may be irrelevant. This was shortly after startup. I also had just switched to the Java perspective. It may have just been decorating the elements in the package explorer and/or navigator.
*** Bug 90104 has been marked as a duplicate of this bug. ***
*** Bug 92008 has been marked as a duplicate of this bug. ***
This happens because the decoration thread owns a scheduling rule, DecorationScheduler$1. When a thread tries to get another rule that is unrelated to the one it already owns, this exception is thrown. This is done to prevent the possibility of deadlock (Thread 1 owns rule A and is waiting for rule B, Thread 2 owns rule B and is waiting for rule A). Unfortunately it means either you can't use scheduling rules while calling third party code, or decorators should not be obtaining other scheduling rules during decoration.
The main issue we have here is that we cannot create a top level scheduling rule - you are always in conflict if someone grabs the workspace rule whether or not you care about the workspace (which I don't). As a workaround it was suggested that I have each job check the state of the other before they run.
*** Bug 92057 has been marked as a duplicate of this bug. ***
I was suggesting fixing up the rule in dup bug 92057, but maybe this isn't a good idea from reading previous comments. Questions for JohnA about locking strategy: - why cannot Thread 1 (owning lock A) acquire unrelated lock B, if nobody locked on B ? - if someone is already locked on B, couldn't it rather use active waiting on Thread 1 rather than completing abruptely ?
Note that this problem is meant to occur more often since we made CP initialization more lazy to speed up startup.
I think Philippes idea is also good from a Thread load perspective. A first pass at this really increased the worker threads because of the constant rescheduling. I'll attach my first pass as a patch but I a mstill not happy with it. Phillippe by active waiting do you mean doing a check of a flag than a sleep? That will work fine for a background job but we will need to worry about responsiveness for a UI job. Another thing to consider is using the UI job to block the decoration job but not the other way around as we don't post an update until decoration is done. John I'll need some help on this one as it is much tougher if we can't use scheduling rules.
Created attachment 20182 [details] Patch of the first pass
Yes, but active waiting, I did mean allow it to ping & wait if unable to perform. Isn't it a situation where a progress dialog opens already ? I suspect however it is not meant for such actions, since there is no user action at work here.
Just more thoughts... what if decoration was simply ONE job with its own workqueue. If it is still active, when posting more decoration work, then the job would append to its workqueue. If not active, then it would schedule one decoration job. So at most, there would only be one decoration job, and no need to use any rules.
It is - the problem is that it needs to run all of it's updates in the UI Thread (as they are generally viewers) and the long work of decoration is done in the background. I like your idea though - if we block the decoration but not the updates then we get the desired results as it is decoration that drives the updating.
This is something similar to our background indexing story approach.
Thanks for input Philippe - I have releaseda fix for this to build >20050421. Now I am no longer doing any blocking on the update jobs. The decoration job checks if there is an update pending and if so will sleep for 100ms at a time until the updates are done. As I mentioned before updates are not requested until all decoration is done so this will only be an issue when more decoration requests occur during update. In many cases the results will still be ready - if not we will decorate the new items later. I am going to mark this performance as it makes the updates much snappier as they are not blocked once requested anymore.
Philippe, see bug 92085 for a discussion of the design of scheduling rules. By design it does not allow waiting for a rule while holding a rule. This design means that deadlock among scheduling rules is impossible. It's true that hold and wait doesn't guarantee that a deadlock will happen, but it makes it likely. It looks like since the recent JDT core changes, classpath container initialization now usually happens in the decorator thread instead of during creation of working copies. I think this is good news - it means all this expensive work will now typically happen in a background thread, avoiding a big hit for the user when they run the first operation that requires classpaths to be initialized.
It is good an bad, since it may occur anywhere now... just a timing issue. <g>
Verified in 20050510