Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Redor2021-03-05 21:58:50 +0000
committerLaurent Redor2021-03-08 18:34:01 +0000
commitef2d04e958c6cda02fdc3b79910a40c762f8d52f (patch)
tree9c6d6587dec439b9821665a34eb11458b1a123d9
parent03287238841b5619088ac58bac13afe02212e20e (diff)
downloadorg.eclipse.sirius-ef2d04e958c6cda02fdc3b79910a40c762f8d52f.tar.gz
org.eclipse.sirius-ef2d04e958c6cda02fdc3b79910a40c762f8d52f.tar.xz
org.eclipse.sirius-ef2d04e958c6cda02fdc3b79910a40c762f8d52f.zip
[571249] Avoid potential SWTException exception: "Widget is disposed"v6.4.2rc4
This commit fixes the problem seen during validation (comment 7 [1] of the issue): * To avoid the "Widget is disposed" problem that occurs during the UpdateRequest runnable launched in async by the DeferredUpdateManager, the executions of them are forced before cleaning a the offscreen diagram EditPart. * The dispose of the shell is now done in MappingBasedSiriusFormatManagerFactory.cleanAndDispose(DiagramEditPart). Indeed, running it in async caused a problem with the above change. * All the diagramEditPart are disposed. This is a not a problem detected but a potential problem seen during analysis. [1] https://bugs.eclipse.org/bugs/show_bug.cgi?id=571249#c7 Bug: 571249 Change-Id: Ib58067fd0cdceb77d42fd9f53ab4118a5525e4dd Signed-off-by: Laurent Redor <laurent.redor@obeo.fr>
-rw-r--r--plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/api/format/MappingBasedSiriusFormatManagerFactory.java59
1 files changed, 37 insertions, 22 deletions
diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/api/format/MappingBasedSiriusFormatManagerFactory.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/api/format/MappingBasedSiriusFormatManagerFactory.java
index 719533e17d..1032c07f86 100644
--- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/api/format/MappingBasedSiriusFormatManagerFactory.java
+++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/tools/api/format/MappingBasedSiriusFormatManagerFactory.java
@@ -42,6 +42,7 @@ import org.eclipse.sirius.business.api.dialect.DialectManager;
import org.eclipse.sirius.business.api.session.CustomDataConstants;
import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.common.tools.api.util.EqualityHelper;
+import org.eclipse.sirius.common.ui.tools.api.util.EclipseUIUtil;
import org.eclipse.sirius.diagram.DDiagram;
import org.eclipse.sirius.diagram.DDiagramElement;
import org.eclipse.sirius.diagram.DNode;
@@ -71,7 +72,7 @@ import org.eclipse.sirius.viewpoint.DRepresentation;
import org.eclipse.sirius.viewpoint.description.RepresentationDescription;
import org.eclipse.sirius.viewpoint.description.Viewpoint;
import org.eclipse.sirius.viewpoint.provider.SiriusEditPlugin;
-import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
/**
@@ -222,9 +223,11 @@ public class MappingBasedSiriusFormatManagerFactory {
synchronizeTargetDiagram(targetSession, (DSemanticDiagram) targetDiagram);
DiagramEditPart sourceDiagramEditPart = null;
DiagramEditPart targetDiagramEditPart = null;
+ Collection<DiagramEditPart> sourceDiagramEditParts = null;
+ Collection<DiagramEditPart> targetDiagramEditParts = null;
try {
- Collection<DiagramEditPart> sourceDiagramEditParts = getDiagramEditPart(sourceSession, sourceDiagram);
- Collection<DiagramEditPart> targetDiagramEditParts = getDiagramEditPart(targetSession, targetDiagram);
+ sourceDiagramEditParts = getDiagramEditPart(sourceSession, sourceDiagram);
+ targetDiagramEditParts = getDiagramEditPart(targetSession, targetDiagram);
if (!sourceDiagramEditParts.isEmpty() && !targetDiagramEditParts.isEmpty()) {
sourceDiagramEditPart = sourceDiagramEditParts.stream().findFirst().get();
@@ -244,11 +247,18 @@ public class MappingBasedSiriusFormatManagerFactory {
synchronizeTargetDiagram(targetSession, (DSemanticDiagram) targetDiagram);
}
} finally {
- if (sourceDiagramEditPart != null) {
- cleanAndDispose(sourceDiagramEditPart);
+ // Several org.eclipse.draw2d.DeferredUpdateManager (UpdateRequest) could be launched, in async, during the
+ // paste process.
+ // We should execute them to avoid potential "Widget is disposed" during the cleanAndDispose.
+ EclipseUIUtil.synchronizeWithUIThread();
+ // Even if in theory, only one diagram is created, the above code can create several DiagramEditParts for
+ // source and target, so we clean all of them and not directly sourceDiagramEditPart and
+ // targetDiagramEditPart
+ if (sourceDiagramEditParts != null) {
+ sourceDiagramEditParts.stream().forEach(dep -> cleanAndDispose(dep));
}
- if (targetDiagramEditPart != null) {
- cleanAndDispose(targetDiagramEditPart);
+ if (targetDiagramEditParts != null) {
+ targetDiagramEditParts.stream().forEach(dep -> cleanAndDispose(dep));
}
}
}
@@ -536,6 +546,7 @@ public class MappingBasedSiriusFormatManagerFactory {
private Collection<DiagramEditPart> getDiagramEditPart(Session session, DRepresentation representation) {
final List<DiagramEditPart> result = new ArrayList<DiagramEditPart>();
final Collection<EObject> data = session.getServices().getCustomData(CustomDataConstants.GMF_DIAGRAMS, representation);
+ // Create a new shell for the diagramEditPart, it will be disposed later in cleanAndDispose(DiagramEditPart).
Shell shell = new Shell();
for (final EObject dataElement : data) {
if (dataElement instanceof Diagram) {
@@ -545,12 +556,6 @@ public class MappingBasedSiriusFormatManagerFactory {
result.add(diagramEditPart);
}
}
- Display.getCurrent().asyncExec(new Runnable() {
- @Override
- public void run() {
- shell.dispose();
- }
- });
return result;
}
@@ -744,16 +749,26 @@ public class MappingBasedSiriusFormatManagerFactory {
* Clean {@code diagramEditPart} element to avoid memory leaks.
*
* @param diagramEditPart
+ * The diagram edit part to dispose and to use to also dispose associated elements.
*/
private void cleanAndDispose(DiagramEditPart diagramEditPart) {
- // Clean to avoid memory leaks
- diagramEditPart.deactivate();
- // Memory leak : also disposing the
- // DiagramGraphicalViewer associated to this
- // DiagramEditPart
- diagramEditPart.getViewer().flush();
- diagramEditPart.getViewer().getEditDomain().getCommandStack().flush();
- diagramEditPart.getViewer().getControl().dispose();
- ((DiagramEditDomain) diagramEditPart.getViewer().getEditDomain()).removeViewer(diagramEditPart.getViewer());
+ if (diagramEditPart != null) {
+ // Clean to avoid memory leaks
+ diagramEditPart.deactivate();
+ // Memory leak : also disposing the
+ // DiagramGraphicalViewer associated to this
+ // DiagramEditPart
+ diagramEditPart.getViewer().flush();
+ diagramEditPart.getViewer().getEditDomain().getCommandStack().flush();
+ Control control = diagramEditPart.getViewer().getControl();
+ if (control.getParent() != null) {
+ // Dispose the shell created in method getDiagramEditPart(Session, DRepresentation).
+ control.getParent().dispose();
+ } else {
+ // This code should not occurred, but it's just to be sure.
+ control.isDisposed();
+ }
+ ((DiagramEditDomain) diagramEditPart.getViewer().getEditDomain()).removeViewer(diagramEditPart.getViewer());
+ }
}
}

Back to the top