Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 336080

Summary: Closing the DS editor with cmd-w causes deadlock
Product: [Eclipse Project] PDE Reporter: Bryan Hunt <bhunt>
Component: UIAssignee: Dani Megert <daniel_megert>
Status: VERIFIED FIXED QA Contact:
Severity: major    
Priority: P3 CC: curtis.windatt.public, daniel_megert, eclipse, gunnar, markus.kell.r, remy.suen, vstevanovic
Version: 3.7Flags: curtis.windatt.public: review+
Target Milestone: 3.7 RC1   
Hardware: PC   
OS: Mac OS X - Carbon (unsup.)   
Whiteboard:
Attachments:
Description Flags
Dirty hack
none
Possible fix none

Description Bryan Hunt CLA 2011-02-02 10:42:52 EST
If you close the DS editor with cmd-w immediately after a save, Eclipse will deadlock and you have to kill it.
Comment 1 Bryan Hunt CLA 2011-03-25 14:38:23 EDT
I captured some additional info during this hang condition - I've deleted the stacks that did not appear relevant ...

Stacks at 01:29:39 PM (uptime 4:48:11)

main [WAITING] CPU time: 6:01
java.lang.Object.wait()
org.eclipse.jface.text.reconciler.AbstractReconciler$BackgroundThread.suspendCallerWhileDirty()
org.eclipse.jface.text.reconciler.AbstractReconciler$Listener.inputDocumentAboutToBeChanged(IDocument, IDocument)
org.eclipse.jface.text.reconciler.AbstractReconciler.uninstall()
org.eclipse.jface.text.source.SourceViewer.unconfigure()
org.eclipse.pde.internal.ui.editor.PDEProjectionViewer.unconfigure()
org.eclipse.jface.text.source.SourceViewer.handleDispose()
org.eclipse.jface.text.source.projection.ProjectionViewer.handleDispose()
org.eclipse.jface.text.TextViewer$2.widgetDisposed(DisposeEvent)
org.eclipse.swt.widgets.TypedListener.handleEvent(Event)
org.eclipse.swt.widgets.EventTable.sendEvent(Event)
org.eclipse.swt.widgets.Display.sendEvent(EventTable, Event)
org.eclipse.swt.widgets.Widget.sendEvent(Event)
org.eclipse.swt.widgets.Widget.sendEvent(int, Event, boolean)
org.eclipse.swt.widgets.Widget.sendEvent(int, Event)
org.eclipse.swt.widgets.Widget.notifyListeners(int, Event)
org.eclipse.swt.custom.StyledText.handleDispose(Event)
org.eclipse.swt.custom.StyledText$7.handleEvent(Event)
org.eclipse.swt.widgets.EventTable.sendEvent(Event)
org.eclipse.swt.widgets.Display.sendEvent(EventTable, Event)
org.eclipse.swt.widgets.Widget.sendEvent(Event)
org.eclipse.swt.widgets.Widget.sendEvent(int, Event, boolean)
org.eclipse.swt.widgets.Widget.sendEvent(int)
org.eclipse.swt.widgets.Widget.release(boolean)
org.eclipse.swt.widgets.Control.release(boolean)
org.eclipse.swt.widgets.Composite.releaseChildren(boolean)
org.eclipse.swt.widgets.Canvas.releaseChildren(boolean)
org.eclipse.swt.widgets.Widget.release(boolean)
org.eclipse.swt.widgets.Control.release(boolean)
org.eclipse.swt.widgets.Composite.releaseChildren(boolean)
org.eclipse.swt.widgets.Widget.release(boolean)
org.eclipse.swt.widgets.Control.release(boolean)
org.eclipse.swt.widgets.Composite.releaseChildren(boolean)
org.eclipse.swt.widgets.Widget.release(boolean)
org.eclipse.swt.widgets.Control.release(boolean)
org.eclipse.swt.widgets.Composite.releaseChildren(boolean)
org.eclipse.swt.widgets.Widget.release(boolean)
org.eclipse.swt.widgets.Control.release(boolean)
org.eclipse.swt.widgets.Composite.releaseChildren(boolean)
org.eclipse.swt.widgets.Widget.release(boolean)
org.eclipse.swt.widgets.Control.release(boolean)
org.eclipse.swt.widgets.Composite.releaseChildren(boolean)
org.eclipse.swt.widgets.Widget.release(boolean)
org.eclipse.swt.widgets.Control.release(boolean)
org.eclipse.swt.widgets.Composite.releaseChildren(boolean)
org.eclipse.swt.widgets.Widget.release(boolean)
org.eclipse.swt.widgets.Control.release(boolean)
org.eclipse.swt.widgets.Widget.dispose()
org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.disposeWidget(MUIElement)
org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeRemoveGui(MUIElement)
org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$2(PartRenderingEngine, MUIElement)
org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$6.run()
org.eclipse.core.runtime.SafeRunner.run(ISafeRunnable)
org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.removeGui(MUIElement)
org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$1.handleEvent(Event)
org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run()
org.eclipse.swt.widgets.Synchronizer.syncExec(Runnable)
org.eclipse.ui.internal.UISynchronizer.syncExec(Runnable)
org.eclipse.swt.widgets.Display.syncExec(Runnable)
org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(Runnable)
org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(Event)
org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(Event, Permission)
org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerWrapper, Permission, int, Event)
org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(Object, Object, int, Object)
org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(Set, EventDispatcher, int, Object)
org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(int, Object)
org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(Event, boolean)
org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(Event)
org.eclipse.equinox.internal.event.EventComponent.sendEvent(Event)
org.eclipse.e4.ui.services.internal.events.EventBroker.send(String, Object)
org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(Notification)
org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(Notification)
org.eclipse.e4.ui.model.application.ui.impl.UIElementImpl.setToBeRendered(boolean)
org.eclipse.e4.ui.internal.workbench.PartServiceImpl.hidePart(MPart, boolean)
org.eclipse.ui.internal.WorkbenchPage.hidePart(MPart, boolean, boolean, boolean, boolean)
org.eclipse.ui.internal.WorkbenchPage.hidePart(MPart, boolean, boolean, boolean)
org.eclipse.ui.internal.WorkbenchPage.closeEditors(IEditorReference[], boolean)
org.eclipse.ui.internal.WorkbenchPage.closeEditor(IEditorPart, boolean)
org.eclipse.ui.internal.CloseEditorHandler.execute(ExecutionEvent)
org.eclipse.ui.internal.handlers.HandlerProxy.execute(ExecutionEvent)
org.eclipse.ui.internal.handlers.E4HandlerProxy.execute(IEclipseContext, Map)
java.lang.reflect.Method.invoke(Object, Object[])
org.eclipse.e4.core.internal.di.MethodRequestor.execute()
org.eclipse.e4.core.internal.di.InjectorImpl.invokeUsingClass(Object, Class, Class, Object, PrimaryObjectSupplier, PrimaryObjectSupplier, boolean)
org.eclipse.e4.core.internal.di.InjectorImpl.invoke(Object, Class, Object, PrimaryObjectSupplier, PrimaryObjectSupplier)
org.eclipse.e4.core.contexts.ContextInjectionFactory.invoke(Object, Class, IEclipseContext, IEclipseContext, Object)
org.eclipse.e4.core.commands.internal.HandlerServiceImpl.executeHandler(ParameterizedCommand)
org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.executeCommand(ParameterizedCommand, Event)
org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.press(List, Event)
org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.processKeyEvent(List, Event)
org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.filterKeySequenceBindings(Event)
org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.access$0(KeyBindingDispatcher, Event)
org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher$KeyDownFilter.handleEvent(Event)
org.eclipse.swt.widgets.EventTable.sendEvent(Event)
org.eclipse.swt.widgets.Display.filterEvent(Event)
org.eclipse.swt.widgets.Display.sendEvent(EventTable, Event)
org.eclipse.swt.widgets.Widget.sendEvent(Event)
org.eclipse.swt.widgets.Widget.sendEvent(int, Event, boolean)
org.eclipse.swt.widgets.Widget.sendEvent(int, Event)
org.eclipse.swt.widgets.Widget.sendKeyEvent(int, Event)
org.eclipse.swt.widgets.Widget.sendKeyEvent(NSEvent, int)
org.eclipse.swt.widgets.Table.sendKeyEvent(NSEvent, int)
org.eclipse.swt.widgets.Control.keyDown(long, long, long)
org.eclipse.swt.widgets.Composite.keyDown(long, long, long)
org.eclipse.swt.widgets.Table.keyDown(long, long, long)
org.eclipse.swt.widgets.Display.windowProc(long, long, long)
org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(objc_super, long, long)
org.eclipse.swt.widgets.Widget.callSuper(long, long, long)
org.eclipse.swt.widgets.Widget.windowSendEvent(long, long, long)
org.eclipse.swt.widgets.Shell.windowSendEvent(long, long, long)
org.eclipse.swt.widgets.Display.windowProc(long, long, long)
org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(objc_super, long, long)
org.eclipse.swt.widgets.Display.applicationSendEvent(long, long, long)
org.eclipse.swt.widgets.Display.applicationProc(long, long, long)
org.eclipse.swt.internal.cocoa.OS.objc_msgSend(long, long, long)
org.eclipse.swt.internal.cocoa.NSApplication.sendEvent(NSEvent)
org.eclipse.swt.widgets.Display.readAndDispatch()
org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$7.run()
org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm, Runnable)
org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(MApplicationElement, IEclipseContext)
org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(MApplicationElement)
org.eclipse.ui.internal.Workbench$3.run()
org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm, Runnable)
org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor)
org.eclipse.ui.PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor)
org.eclipse.ui.internal.ide.application.IDEApplication.start(IApplicationContext)
org.eclipse.equinox.internal.app.EclipseAppHandle.run(Object)
org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(Object)
org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(Object)
org.eclipse.core.runtime.adaptor.EclipseStarter.run(Object)
org.eclipse.core.runtime.adaptor.EclipseStarter.run(String[], Runnable)
java.lang.reflect.Method.invoke(Object, Object[])
org.eclipse.equinox.launcher.Main.invokeFramework(String[], URL[])
org.eclipse.equinox.launcher.Main.basicRun(String[])
org.eclipse.equinox.launcher.Main.run(String[])


org.eclipse.jface.text.reconciler.Reconciler [WAITING] CPU time: 0:00
java.lang.Object.wait()
org.eclipse.swt.widgets.Synchronizer.syncExec(Runnable)
org.eclipse.ui.internal.UISynchronizer.syncExec(Runnable)
org.eclipse.swt.widgets.Display.syncExec(Runnable)
org.eclipse.pde.internal.ds.ui.editor.sections.DSComponentSection.modelChanged(IModelChangedEvent)
org.eclipse.pde.internal.core.text.AbstractEditingModel.fireModelChanged(IModelChangedEvent)
org.eclipse.pde.internal.core.text.AbstractEditingModel.reload(InputStream, boolean)
org.eclipse.pde.internal.core.text.AbstractEditingModel.reconciled(IDocument)
org.eclipse.pde.internal.ui.editor.text.ReconcilingStrategy.notifyParticipants()
org.eclipse.pde.internal.ui.editor.text.ReconcilingStrategy.reconcile(DirtyRegion, IRegion)
org.eclipse.jface.text.reconciler.Reconciler.process(DirtyRegion)
org.eclipse.jface.text.reconciler.AbstractReconciler$BackgroundThread.run()
Comment 2 Gunnar Wagenknecht CLA 2011-03-25 18:48:44 EDT
CC'ing Dani as this looks like a JFace Text issue. Note, you are using e4. I also get the deadlock on 3.7M6.
Comment 3 Dani Megert CLA 2011-03-26 03:36:11 EDT
I'll take a look
Comment 4 Vladimir Stevanovic CLA 2011-04-01 08:40:48 EDT
*** Bug 341606 has been marked as a duplicate of this bug. ***
Comment 5 Dani Megert CLA 2011-04-01 09:50:58 EDT
Which version (build id) do you use?
Comment 6 Bryan Hunt CLA 2011-04-01 10:10:19 EDT
The stack traces are from 4.1M6
Comment 7 Dani Megert CLA 2011-04-01 10:36:17 EDT
Ugly! The DSComponentSection which should update the model (not UI) posts events synchronously into the UI thread. This is not allowed from within the reconciler thread as this can easily cause deadlocks like we see here. The DSOptionsSection has the same bug.

Moving back to PDE UI inbox to see how they can get rid of this.

I'll attach a dirty hack that will prevent the deadlock. However, it will cause widget disposed errors being written to .log.
Comment 8 Dani Megert CLA 2011-04-01 10:37:06 EDT
Created attachment 192366 [details]
Dirty hack
Comment 9 Dani Megert CLA 2011-04-01 10:38:04 EDT
*** Bug 312187 has been marked as a duplicate of this bug. ***
Comment 10 Dani Megert CLA 2011-04-02 03:05:12 EDT
Created attachment 192413 [details]
Possible fix

Ankur or Curtis: I've attached a possible fix but it needs some testing and a review. Also, a second check whether other places are also calling syncExec from the reconciler needs to be performed.

BTW: Display.getDisplay() should never be used.
Comment 11 Curtis Windatt CLA 2011-04-15 10:58:19 EDT
Moving to RC1
Comment 12 Dani Megert CLA 2011-05-02 09:54:53 EDT
+1 for RC1.
Comment 13 Curtis Windatt CLA 2011-05-04 15:56:26 EDT
+1, patch applied to HEAD.

I don't see anywhere else in PDE where we are using syncExec when updating models.  We are however using Display.getDefault() in the product editor and elsewhere, I filed bug 344759.
Comment 14 Dani Megert CLA 2011-05-05 03:12:03 EDT
(In reply to comment #13)
> +1, patch applied to HEAD.

Curtis, it would be nice to mention the patch creator/author in the comment ;-).
Comment 15 Curtis Windatt CLA 2011-05-05 09:56:43 EDT
(In reply to comment #14)
> Curtis, it would be nice to mention the patch creator/author in the comment
> ;-).

Thanks for the patch Dani :)

I did reassign the bug to you.  I didn't mark this as contributed because you are a committer.
Comment 16 Dani Megert CLA 2011-05-05 10:01:11 EDT
(In reply to comment #15)
> (In reply to comment #14)
> > Curtis, it would be nice to mention the patch creator/author in the comment
> > ;-).
> 
> Thanks for the patch Dani :)
> 
> I did reassign the bug to you.  I didn't mark this as contributed because you
> are a committer.

I meant in the CVS commit comment :-)
Comment 17 Markus Keller CLA 2011-05-16 13:25:41 EDT
Verified in I20110512-2000 that the deadlock is gone. Filed bug 345987 for the remaining widget disposed exceptions.
Comment 18 Dani Megert CLA 2011-06-01 08:27:06 EDT
*** Bug 322982 has been marked as a duplicate of this bug. ***