Bug 86628 - [Decorators] IAE: beginRule: R/, does not match outer scope rule
Summary: [Decorators] IAE: beginRule: R/, does not match outer scope rule
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.0   Edit
Hardware: PC Windows 2000
: P2 normal (vote)
Target Milestone: 3.1 M7   Edit
Assignee: Tod Creasey CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 90104 92008 92057 (view as bug list)
Depends on: 92085
Blocks:
  Show dependency tree
 
Reported: 2005-02-25 09:48 EST by Nick Edgar CLA
Modified: 2005-05-10 14:38 EDT (History)
4 users (show)

See Also:


Attachments
Patch of the first pass (3.87 KB, patch)
2005-04-21 09:07 EDT, Tod Creasey CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Edgar CLA 2005-02-25 09:48:15 EST
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)
Comment 1 Nick Edgar CLA 2005-02-25 09:49:14 EST
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.
Comment 2 Tod Creasey CLA 2005-04-04 08:30:07 EDT
*** Bug 90104 has been marked as a duplicate of this bug. ***
Comment 3 Tod Creasey CLA 2005-04-20 08:30:04 EDT
*** Bug 92008 has been marked as a duplicate of this bug. ***
Comment 4 John Arthorne CLA 2005-04-20 10:03:23 EDT
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.
Comment 5 Tod Creasey CLA 2005-04-20 10:55:54 EDT
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.
Comment 6 Philipe Mulet CLA 2005-04-21 07:17:06 EDT
*** Bug 92057 has been marked as a duplicate of this bug. ***
Comment 7 Philipe Mulet CLA 2005-04-21 07:23:56 EDT
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 ?
Comment 8 Philipe Mulet CLA 2005-04-21 07:24:47 EDT
Note that this problem is meant to occur more often since we made CP
initialization more lazy to speed up startup.
Comment 9 Tod Creasey CLA 2005-04-21 09:06:08 EDT
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.
Comment 10 Tod Creasey CLA 2005-04-21 09:07:15 EDT
Created attachment 20182 [details]
Patch of the first pass
Comment 11 Philipe Mulet CLA 2005-04-21 09:21:30 EDT
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.
Comment 12 Philipe Mulet CLA 2005-04-21 09:23:39 EDT
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.
Comment 13 Tod Creasey CLA 2005-04-21 09:31:41 EDT
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.
Comment 14 Philipe Mulet CLA 2005-04-21 09:56:51 EDT
This is something similar to our background indexing story approach.
Comment 15 Tod Creasey CLA 2005-04-21 10:14:36 EDT
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.
Comment 16 John Arthorne CLA 2005-04-21 10:20:11 EDT
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.
Comment 17 Philipe Mulet CLA 2005-04-21 15:55:12 EDT
It is good an bad, since it may occur anywhere now... just a timing issue. <g>
Comment 18 Tod Creasey CLA 2005-05-10 14:38:08 EDT
Verified in 20050510