Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 319198 - [javadoc] Deadlock in SynchronizableDocument
Summary: [javadoc] Deadlock in SynchronizableDocument
Status: CLOSED WONTFIX
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Compare (show other bugs)
Version: 3.6   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Platform-Compare-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
Depends on:
Blocks:
 
Reported: 2010-07-07 18:30 EDT by Matt Lavin CLA
Modified: 2021-12-02 12:42 EST (History)
1 user (show)

See Also:


Attachments
Zipped javacore file showing deadlocked threads (429.63 KB, application/zip)
2010-07-07 18:30 EDT, Matt Lavin CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Matt Lavin CLA 2010-07-07 18:30:55 EDT
Created attachment 173724 [details]
Zipped javacore file showing deadlocked threads

My IDE recently became unresponsive and I captured a javacore to explain why.  The UI thread is blocked as follows:

at org/eclipse/core/internal/filebuffers/SynchronizableDocument.getModificationStamp(SynchronizableDocument.java:166(Compiled Code)) at org/eclipse/text/undo/DocumentUndoManager$UndoableTextChange.canUndo(DocumentUndoManager.java:160(Compiled Code)) at org/eclipse/core/commands/operations/DefaultOperationHistory.canUndo(DefaultOperationHistory.java:269(Compiled Code)) at org/eclipse/ui/operations/UndoActionHandler.shouldBeEnabled(UndoActionHandler.java:82) at org/eclipse/ui/operations/OperationHistoryActionHandler.update(OperationHistoryActionHandler.java:438) at org/eclipse/ui/operations/OperationHistoryActionHandler$1.run(OperationHistoryActionHandler.java:144) at org/eclipse/swt/widgets/RunnableLock.run(RunnableLock.java:35(Compiled Code)) at org/eclipse/swt/widgets/Synchronizer.runAsyncMessages(Synchronizer.java:130(Compiled Code)) at org/eclipse/swt/widgets/Display.runAsyncMessages(Display.java:3527(Compiled Code)) at org/eclipse/swt/widgets/Display.readAndDispatch(Display.java:3164(Compiled Code)) at org/eclipse/ui/internal/Workbench.runEventLoop(Workbench.java:2629) at org/eclipse/ui/internal/Workbench.runUI(Workbench.java:2593) at org/eclipse/ui/internal/Workbench.access$4(Workbench.java:2427) at org/eclipse/ui/internal/Workbench$7.run(Workbench.java:670) at org/eclipse/core/databinding/observable/Realm.runWithDefault(Realm.java:332) at org/eclipse/ui/internal/Workbench.createAndRunWorkbench(Workbench.java:663) at org/eclipse/ui/PlatformUI.createAndRunWorkbench(PlatformUI.java:149) at org/eclipse/ui/internal/ide/application/IDEApplication.start(IDEApplication.java:115) at org/eclipse/equinox/internal/app/EclipseAppHandle.run(EclipseAppHandle.java:196) at org/eclipse/core/runtime/internal/adaptor/EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110) at org/eclipse/core/runtime/internal/adaptor/EclipseAppLauncher.start(EclipseAppLauncher.java:79) at org/eclipse/core/runtime/adaptor/EclipseStarter.run(EclipseStarter.java:369) at org/eclipse/core/runtime/adaptor/EclipseStarter.run(EclipseStarter.java:179) at sun/reflect/NativeMethodAccessorImpl.invoke0(Native Method) at sun/reflect/NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48) at sun/reflect/DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java/lang/reflect/Method.invoke(Method.java:600) at org/eclipse/equinox/launcher/Main.invokeFramework(Main.java:619) at org/eclipse/equinox/launcher/Main.basicRun(Main.java:574) at org/eclipse/equinox/launcher/Main.run(Main.java:1407) at org/eclipse/equinox/launcher/Main.main(Main.java:1383)

The thread that is holding the lock that the UI is waiting for is also waiting on the UI thread to complete it's operation (hence the deadlock):

at java/lang/Object.wait(Native Method) at java/lang/Object.wait(Object.java:196(Compiled Code)) at org/eclipse/ui/internal/Semaphore.acquire(Semaphore.java:30(Compiled Code)) at org/eclipse/ui/internal/UISynchronizer.syncExec(UISynchronizer.java:134(Compiled Code)) at org/eclipse/swt/widgets/Display.syncExec(Display.java:4294(Compiled Code)) at org/eclipse/compare/internal/Utilities.firePropertyChange(Utilities.java:166) at org/eclipse/compare/internal/Utilities.firePropertyChange(Utilities.java:140) at org/eclipse/compare/contentmergeviewer/ContentMergeViewer.fireDirtyState(ContentMergeViewer.java:1156) at org/eclipse/compare/contentmergeviewer/ContentMergeViewer.setLeftDirty(ContentMergeViewer.java:1173) at org/eclipse/compare/contentmergeviewer/TextMergeViewer.updateDirtyState(TextMergeViewer.java:3038) at org/eclipse/compare/contentmergeviewer/TextMergeViewer.access$12(TextMergeViewer.java:3032) at org/eclipse/compare/contentmergeviewer/TextMergeViewer$ContributorInfo.elementDirtyStateChanged(TextMergeViewer.java:1005) at org/eclipse/ui/editors/text/TextFileDocumentProvider$FileBufferListener.dirtyStateChanged(TextFileDocumentProvider.java:288(Compiled Code)) at org/eclipse/core/internal/filebuffers/TextFileBufferManager$3.run(TextFileBufferManager.java:706) at org/eclipse/core/runtime/SafeRunner.run(SafeRunner.java:42(Compiled Code)) at org/eclipse/core/internal/filebuffers/TextFileBufferManager.fireDirtyStateChanged(TextFileBufferManager.java:704) at org/eclipse/core/internal/filebuffers/ResourceTextFileBuffer$DocumentListener.documentChanged(ResourceTextFileBuffer.java:77) at org/eclipse/jface/text/AbstractDocument.doFireDocumentChanged2(AbstractDocument.java:769(Compiled Code)) at org/eclipse/jface/text/AbstractDocument.doFireDocumentChanged(AbstractDocument.java:736(Compiled Code)) at org/eclipse/jface/text/AbstractDocument.doFireDocumentChanged(AbstractDocument.java:719(Compiled Code)) at org/eclipse/jface/text/AbstractDocument.fireDocumentChanged(AbstractDocument.java:796(Compiled Code)) at org/eclipse/jface/text/AbstractDocument.replace(AbstractDocument.java:1191(Compiled Code)) at org/eclipse/core/internal/filebuffers/SynchronizableDocument.replace(SynchronizableDocument.java:195) at org/eclipse/jface/text/AbstractDocument.replace(AbstractDocument.java:1210(Compiled Code)) at org/eclipse/core/internal/filebuffers/SynchronizableDocument.replace(SynchronizableDocument.java:180(Compiled Code)) at org/eclipse/text/edits/DeleteEdit.performDocumentUpdating(DeleteEdit.java:64(Compiled Code)) at org/eclipse/text/edits/TextEdit.traverseDocumentUpdating(TextEdit.java:917(Compiled Code)) at org/eclipse/text/edits/TextEdit.traverseDocumentUpdating(TextEdit.java:910(Compiled Code)) at org/eclipse/text/edits/TextEditProcessor.executeDo(TextEditProcessor.java:195(Compiled Code)) at org/eclipse/text/edits/TextEdit.dispatchPerformEdits(TextEdit.java:739(Compiled Code)) at org/eclipse/text/edits/TextEditProcessor.performEdits(TextEditProcessor.java:150(Compiled Code)) at org/eclipse/text/edits/TextEdit.apply(TextEdit.java:710(Compiled Code)) at org/eclipse/text/edits/TextEdit.apply(TextEdit.java:735(Compiled Code)) at com/ibm/team/codegen/internal/query/UnusedImportRemover.removeUnusedImports(UnusedImportRemover.java:103(Compiled Code)) at com/ibm/team/codegen/internal/query/UnusedImportRemover.access$1(UnusedImportRemover.java:101) at com/ibm/team/codegen/internal/query/UnusedImportRemover$UnusedImportsRequestor.acceptAST(UnusedImportRemover.java:178) at org/eclipse/jdt/core/dom/CompilationUnitResolver.resolve(CompilationUnitResolver.java:883) at org/eclipse/jdt/core/dom/CompilationUnitResolver.resolve(CompilationUnitResolver.java:577) at org/eclipse/jdt/core/dom/ASTParser.createASTs(ASTParser.java:888) at com/ibm/team/codegen/internal/query/UnusedImportRemover.removeUnusedImports(UnusedImportRemover.java:93) at com/ibm/team/codegen/internal/query/QueryModelGen.generate(QueryModelGen.java:254) at com/ibm/team/codegen/internal/CodeGenerator.generateQueryModel(CodeGenerator.java:155) at com/ibm/team/codegen/internal/CodeGenerator.generate(CodeGenerator.java:139) at com/ibm/team/codegen/TeamCodeGen$1.run(TeamCodeGen.java:38) at org/eclipse/core/internal/resources/Workspace.run(Workspace.java:1975(Compiled Code)) at org/eclipse/core/internal/resources/Workspace.run(Workspace.java:1957) at com/ibm/team/codegen/TeamCodeGen.generate(TeamCodeGen.java:41) at com/ibm/team/codegen/ui/actions/GenerateComponentAction.generate(GenerateComponentAction.java:56) at com/ibm/team/codegen/ui/actions/GenerateComponentAction$1.run(GenerateComponentAction.java:34) at org/eclipse/core/internal/jobs/Worker.run(Worker.java:54(Compiled Code))

I've also attached the full javacore file.
Comment 1 Dani Megert CLA 2010-07-09 02:07:25 EDT
The deadlock happens because a third party product applies text edits in the wrong context/thread. This should either be done directly in the UI thread, a modal context or - preferred - by using org.eclipse.core.filebuffers.IFileBufferManager.execute(Runnable).
Comment 2 Matt Lavin CLA 2010-07-09 08:19:52 EDT
(In reply to comment #1)
> The deadlock happens because a third party product applies text edits in the
> wrong context/thread. This should either be done directly in the UI thread, a
> modal context or - preferred - by using
> org.eclipse.core.filebuffers.IFileBufferManager.execute(Runnable).


Thanks for the quick answer.  I didn't realize that the text editing should only happen in the UI thread.  I looked at the Javadoc for TextEdit class and the apply method in particular, but neither had any reference to the method only working on the UI thread.  Would it make sense to fail to execute the method when the wrong thread is used if that is a real requirement?  In my case, the code has been working for >1 year before this problem happened.

Additionally, can you explain why TextEdits can only happen on the UI thread?  Editing file contents seems like a non-UI operation.
Comment 3 Dani Megert CLA 2010-07-09 09:40:42 EDT
>In my
>case, the code has been working for >1 year before this problem happened
Do you have steps? Normally your code will probably work. I assume in this case a compare editor was open on the same file.

>Additionally, can you explain why TextEdits can only happen on the UI thread?
Not the UI thread but the same synchronization context that you apply your edits on. If you do this on a simple document you're fine but in your case you have a synchronized document at hand.

We can improve the Javadoc but there's nothing we can do to fix the deadlock.

>Would it make sense to fail to execute the
>method when the wrong thread is used if that is a real requirement?  
No, because in most cases it will still work.
Comment 4 Dani Megert CLA 2010-07-10 05:15:47 EDT
Actually Compare could resolve the problem by using asyncExec(...) instead of syncExec(...). That's the pattern that should be used to avoid such deadlocks unless there's a proven must-have for syncExec.
Comment 5 Eclipse Webmaster CLA 2019-09-06 16:05:48 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.
Comment 6 Eclipse Genie CLA 2021-12-02 12:42:02 EST
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug.

If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.