From f11afd0efca10b1b9ca2ac7b5bf999cb08276d79 Mon Sep 17 00:00:00 2001
From: Simon Barner <barner@fortiss.org>
Date: Mon, 25 Oct 2021 15:12:05 +0200
Subject: [PATCH] Refresh top level elements only after modelFileChangesJob has
 finished

* Avoids a deadlock with the EclipseResourceStorageService

Issue-Ref: 4166
Issue-Url: https://git.fortiss.org/af3/af3/-/issues/4166

Signed-off-by: Simon Barner <barner@fortiss.org>
---
 .../kernel/internal/storage/eclipse/.ratings  |  2 +-
 .../EclipseResourceStorageService.java        | 28 +++++++++++++------
 2 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/.ratings
index 7194108f3..b7c001b2d 100644
--- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/.ratings
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/.ratings
@@ -1,5 +1,5 @@
 AutoUndoCommandStack.java fc326adf66c6cea2354884cdc240da5f2f82689a GREEN
 EMFTransactionalCommand.java ba4b5bead9768b6ce6c955b9238cd96cb722533c GREEN
-EclipseResourceStorageService.java e917c822c53eacada70188e66215d91241a29a5c GREEN
+EclipseResourceStorageService.java 5e60ef7628ea2ad4113cfebde939341e1b1f6cf2 YELLOW
 ModelContext.java 76eeaef7f56da5f0e288cf96792850be606b7757 YELLOW
 NonDirtyingEMFTransactionalCommand.java d288ebe35d22442c603496b0c917fb99a8febeea GREEN
diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EclipseResourceStorageService.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EclipseResourceStorageService.java
index e917c822c..5e60ef762 100644
--- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EclipseResourceStorageService.java
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EclipseResourceStorageService.java
@@ -49,6 +49,8 @@ import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.resource.Resource;
@@ -202,10 +204,10 @@ public class EclipseResourceStorageService
 
 	/** Runs resource change job as workspace job. */
 	private void runWorkspaceChangeJob(final IFile file, final int changeKind) {
-		new WorkspaceJob("ModelFileChangedJob") {
+		WorkspaceJob modelFileChangesJob = new WorkspaceJob("ModelFileChangedJob") {
 			@Override
 			public IStatus runInWorkspace(IProgressMonitor monitor) {
-				IPersistencyService ps = IPersistencyService.getInstance();
+
 				synchronized(EclipseResourceStorageService.this) {
 					// Model file that is managed by kernel has been changed
 					if(checkLocationProvider(file)) {
@@ -218,11 +220,10 @@ public class EclipseResourceStorageService
 								loadContext(file);
 							}
 						}
-						// Refresh the top-level elements
-						ps.refreshTopLevelElements(EclipseResourceStorageService.this);
 					} else if(changeKind == REMOVED) {
 						// A file has been removed. Remove it from one of the ResourceSets owned by
 						// the kernel.
+						IPersistencyService ps = IPersistencyService.getInstance();
 						for(ITopLevelElement topLevelElement : ps.getTopLevelElements()) {
 							final ResourceSet resourceSet = topLevelElement.getResourceSet();
 							final List<Resource> toRemove = new ArrayList<Resource>();
@@ -256,7 +257,19 @@ public class EclipseResourceStorageService
 				}
 				return Status.OK_STATUS;
 			}
-		}.schedule();
+		};
+
+		// Refresh top level elements after modelFileChangesJob has finished in order to avoid
+		// a deadlock with the EclipseResourceStorageService
+		modelFileChangesJob.addJobChangeListener(new JobChangeAdapter() {
+			@Override
+			public void done(IJobChangeEvent event) {
+				IPersistencyService ps = IPersistencyService.getInstance();
+				ps.refreshTopLevelElements(EclipseResourceStorageService.this);
+			}
+		});
+
+		modelFileChangesJob.schedule();
 	}
 
 	/** Returns whether the given file has been loaded by this manager. */
@@ -380,9 +393,8 @@ public class EclipseResourceStorageService
 	/** {@inheritDoc} */
 	@Override
 	public IIntrospectionDetailsItem getDetailsItem() {
-		return new EclipseResourceStorageKISSDetailsItem(
-				unmodifiableList(storageProviderList), unmodifiableSet(loadedContexts.keySet()),
-				unmodifiableList(errorFiles));
+		return new EclipseResourceStorageKISSDetailsItem(unmodifiableList(storageProviderList),
+				unmodifiableSet(loadedContexts.keySet()), unmodifiableList(errorFiles));
 	}
 
 	/** {@inheritDoc} */
-- 
GitLab