Bug 58314 - Make ASTs thread-safe for multiple readers
Summary: Make ASTs thread-safe for multiple readers
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.0   Edit
Hardware: PC All
: P3 normal (vote)
Target Milestone: 3.0 M9   Edit
Assignee: Jim des Rivieres CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 58428 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-04-13 11:45 EDT by Martin Aeschlimann CLA
Modified: 2004-05-18 13:10 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Aeschlimann CLA 2004-04-13 11:45:43 EDT
20040413

Found this exception in the console.
My guess is that came from visiting the AST from multiple threads. The cursor 
managment doesn't seem to be thread save.


java.lang.NullPointerException
        at java.lang.Throwable.<init>(Throwable.java)
        at java.lang.Throwable.<init>(Throwable.java)
        at java.lang.NullPointerException.<init>(NullPointerException.java:60)
        at org.eclipse.jdt.core.dom.ASTNode$NodeList.releaseCursor
(ASTNode.java)

        at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java)
        at org.eclipse.jdt.core.dom.CompilationUnit.accept0
(CompilationUnit.java
)
        at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java)
        at 
org.eclipse.jdt.internal.ui.javaeditor.OverrideIndicatorManager.updat
eAnnotations(OverrideIndicatorManager.java)
        at 
org.eclipse.jdt.internal.ui.javaeditor.OverrideIndicatorManager.recon
ciled(OverrideIndicatorManager.java:271)
        at 
org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor.reconcil
ed(CompilationUnitEditor.java)
        at 
org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconci
le(JavaReconcilingStrategy.java)
        at 
org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconci
le(JavaReconcilingStrategy.java:118)
        at 
org.eclipse.jface.text.reconciler.CompositeReconcilingStrategy.reconc
ile(CompositeReconcilingStrategy.java)
        at 
org.eclipse.jdt.internal.ui.text.JavaCompositeReconcilingStrategy.rec
oncile(JavaCompositeReconcilingStrategy.java)
        at org.eclipse.jface.text.reconciler.MonoReconciler.process
(MonoReconcil
er.java:76)
        at 
org.eclipse.jface.text.reconciler.AbstractReconciler$BackgroundThread
.run(AbstractReconciler.java)
Comment 1 Olivier Thomann CLA 2004-04-13 12:37:18 EDT
Jim, any comment?
Comment 2 Jim des Rivieres CLA 2004-04-13 13:04:18 EDT
The problem does indeed look like its caused by multiple threads accessing the 
same AST. No aspect of ASTs is thread-safe (not even for just reading).

ASTNode
 * AST nodes are <b>not</b> thread-safe; this is true even for trees that
 * are read-only. If synchronization is required, consider using the common AST
 * object that owns the node; that is, use 
 * <code>synchronize (node.getAST()) {...}</code>.

Comment 3 Jim des Rivieres CLA 2004-04-15 20:50:19 EDT
Reopening. Investigate how to make ASTs thread safe for reading.
Comment 4 Jim des Rivieres CLA 2004-04-15 23:35:37 EDT
Ensuring that AST is safe for separate threads reading the same AST required 
two kinds of changes:
(1) ASTNode.NodeList.newCursor() and releaseCursor().
Both of these methods are used by ASTVisitor while visiting nodes. The methods
modify an internal list of known cursors. Adding internal synch on 
NodeList.this makes these thread-safe for readers. Minor performance impact 
only for ASTVisitors.
(2) various getXXX() methods on node subclasses.
These methods do lazy init, which actually creates new nodes and modifies the 
node being accessed. There are no callbacks during lazy init (there is already 
a mechanism that prevents callbacks from within callbacks). Adding internal 
sync on ASTNode.this make lazy init sequence thread-safe for readers. No issue 
with performance since lazy init is not on critical path (nodes created by 
ASTParser are explicitly init'd).

Updated comment on ASTNode to say that ASTs are safe for multiple readers
(but still utterly unsafe if there are any writers).
Comment 5 Martin Aeschlimann CLA 2004-04-16 03:34:25 EDT
Great, thank a lot, Jim!
I was thinking that some more locks ar required in the BindingResolver at 
places where the binding elements are created and cached.
Comment 6 Jim des Rivieres CLA 2004-04-16 09:14:43 EDT
Reopening while investigating possible need for further locks.
Comment 7 Jim des Rivieres CLA 2004-04-16 12:30:49 EDT
Indeed, two more kinds of changes were required:
(3) AST.disableEvents
Lazy init causes this instance variable to be modified. Adding internal 
sync (on AST.internalAstLock) to make event management thread-safe for readers.
(4) BindingResolver
Any of the methods could be called by a reader. Adding internal 
sync on DefaultBindingResolver to make binding lookup thread-safe for readers.

Comment 8 Martin Aeschlimann CLA 2004-04-18 12:07:11 EDT
*** Bug 58428 has been marked as a duplicate of this bug. ***
Comment 9 Olivier Thomann CLA 2004-05-18 13:10:06 EDT
Verified that code is in 200405180816