Community
Participate
Working Groups
This problem occurs with the I20030129 and M5 builds. From my posts to eclipse.tools: I have ~13 projects in my workspace, 2 of them closed (I couldn't reproduce the problem having them open, but I'm not sure if this means anything). In "Preferences | Workbench | Label Decorations" I have turned on all options. I currently reproduce the problem with the workbench starting in the Resource Perspective by switch to the Java perspective after it has started up. It happened originally after I had done several things to my configuration and simply tried to start eclipse. There are no messages in workspace/.metadata/.log when this happens during startup. The main thread is inside JavaElement.getElementInfo() (line 296() holding the monitor on the JavaModelManager and trying to acquire the workspace lock, while the Decoration thread tries to enter the synchronized method JavaModelManager.getPerProjectInfo() (line 926) while holding the workspace lock (acquired from CVSLightweightDecorator.isDirty() using EclipseFolder.run()). One question that comes to mind is why the call to isDirty triggers a build (shouldn't it just return true or false instead of actually compiling?). I can reproduce the bug in I20030129 and M5, the workspace that I use to reproduce is large and contains several projects I can't share freely. But I'll keep it in order to verify any fixes. (Is there anything else I could provide, apart from trying to reproduce with open source projects?)
Created attachment 3400 [details] Stack of Eclipse in deadlock This is a stacktrace obtained from the Eclipse debugger. In the "Threads and Monitors" view I can see that main is holding the monitor of the JavaModelManager and Decoration is "in contention". I could also provide the workspace .log if that helps (although nothing that seems related is apparent).
This is a classic deadlock case where two threads compete for the same locks but acquire them in a different order. The CVS decorator acquires the workspace lock because of the same type of deadlock ordering between the workspace lock and the CVS synchronizer lock (see bug 29212). There are really two issues here. One is that JDT is open to deadlock because they use two locks and do not gaurantee that they are always acquired in the same order. As bug 29212 points out, this is really a bigger issue that needs to be addressed at some point. The other issue is that the CVS decorator acquires the workspace lock but really shouldn't need to. The case where the CVS decorator can cause a workspace operation involves a deleted file that has not been committed and the first-time reading of the sync info from disk for the parent folder. CVS sync info is stored as a session property on resources that exist but as Core sync info on non-existant resources. Hence, when the sync info is read from disk, the sync info for the phantom representing the deleted file is set to the sync info on disk. The problem is that setting the Core sync info requires the workspace lock. To ensure that dealock would never occur, the workspace lock had to be acquired first (i.e. the best ordering to prevent deadlock was to always acquire the workspace lock before acquiring the CVS lock). However, since the phantom sync info is persisted accross platform invocations, setting it when the sync info is read is a redundant operation. In fact, a check has since been added to avoid setting the sync info of the phantom if the new info is the same as the old. I can't think of any other case where the isDirty check performed by the decorator would cause a workspace operation. The problem is that if one did, then dealock could occur. If the isDirty check were performed outside a workpspace runnable, some mechanism would need be be added to ensure that no workspace operations were performed.
*** Bug 33243 has been marked as a duplicate of this bug. ***
Marking a dupe of 33243. The traces differ but the solution is the same. *** This bug has been marked as a duplicate of 33243 ***
Note that in latest integration build (as of today) we will no longer execute client code inside the JavaModel lock as exhibited here. This is only meant to be an internal cache synchronization lock. This being said, the decoration thread still seems to be doing too much in its own thread, but the JavaModel shouldn't cause a deadlock any longer.