From 0a3ac110124135491d244cddf50be728125aa02a Mon Sep 17 00:00:00 2001 From: Antti Villberg Date: Fri, 20 Jan 2017 09:23:40 +0200 Subject: [PATCH] Undo did not wait for pending cluster updates to finish. refs #6918 Change-Id: I60e8858fa09d69f8793cd5a9c1a3cb20b6682362 (cherry picked from commit 5258d33623db182975901570d58958286397e1e7) --- .../org/simantics/acorn/GraphClientImpl2.java | 184 ++++++++++-------- .../src/org/simantics/acorn/MainProgram.java | 20 ++ 2 files changed, 123 insertions(+), 81 deletions(-) diff --git a/bundles/org.simantics.acorn/src/org/simantics/acorn/GraphClientImpl2.java b/bundles/org.simantics.acorn/src/org/simantics/acorn/GraphClientImpl2.java index 90af336aa..cde943464 100644 --- a/bundles/org.simantics.acorn/src/org/simantics/acorn/GraphClientImpl2.java +++ b/bundles/org.simantics.acorn/src/org/simantics/acorn/GraphClientImpl2.java @@ -21,6 +21,7 @@ import java.util.concurrent.Semaphore; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; +import org.simantics.acorn.MainProgram.MainProgramRunnable; import org.simantics.acorn.exception.AcornAccessVerificationException; import org.simantics.acorn.exception.IllegalAcornStateException; import org.simantics.acorn.internal.ClusterChange; @@ -603,90 +604,111 @@ public class GraphClientImpl2 implements Database.Session { clusters.clusterLRU.releaseMutex(); } } - + @Override public boolean undo(long[] changeSetIds, OnChangeSetUpdate onChangeSetUpdate) throws SDBException { - try { - final ArrayList> clusterChanges = new ArrayList>(); - - UndoClusterSupport support = new UndoClusterSupport(clusters); - - final int changeSetId = clusters.state.headChangeSetId; - - if(ClusterUpdateProcessorBase.DEBUG) - System.err.println(" === BEGIN UNDO ==="); - - for(int i=0;i ccss = clusters.getChanges(id); - - for(int j=0;j pair = clusterChanges.get(i); - - final ClusterUID cuid = pair.first; - final byte[] data = pair.second; - - onChangeSetUpdate.onChangeSetUpdate(new ChangeSetUpdate() { - - @Override - public long getChangeSetId() { - return changeSetId; - } - - @Override - public int getChangeSetIndex() { - return 0; - } - - @Override - public int getNumberOfClusterChangeSets() { - return clusterChanges.size(); - } - - @Override - public int getIndexOfClusterChangeSet() { - return changeSetIndex; - } - - @Override - public byte[] getClusterId() { - return cuid.asBytes(); - } - - @Override - public boolean getNewCluster() { - return false; - } - - @Override - public byte[] getData() { - return data; - } - - }); - } - } catch (AcornAccessVerificationException | IllegalAcornStateException e1) { - throw new ProCoreException(e1); - } + + Exception exception = mainProgram.runIdle(new MainProgramRunnable() { + + @Override + public void run() throws Exception { + + try { + + final ArrayList> clusterChanges = new ArrayList>(); + + UndoClusterSupport support = new UndoClusterSupport(clusters); + + final int changeSetId = clusters.state.headChangeSetId; + + if(ClusterUpdateProcessorBase.DEBUG) + System.err.println(" === BEGIN UNDO ==="); + + for(int i=0;i ccss = clusters.getChanges(id); + + for(int j=0;j pair = clusterChanges.get(i); + + final ClusterUID cuid = pair.first; + final byte[] data = pair.second; + + onChangeSetUpdate.onChangeSetUpdate(new ChangeSetUpdate() { + + @Override + public long getChangeSetId() { + return changeSetId; + } + + @Override + public int getChangeSetIndex() { + return 0; + } + + @Override + public int getNumberOfClusterChangeSets() { + return clusterChanges.size(); + } + + @Override + public int getIndexOfClusterChangeSet() { + return changeSetIndex; + } + + @Override + public byte[] getClusterId() { + return cuid.asBytes(); + } + + @Override + public boolean getNewCluster() { + return false; + } + + @Override + public byte[] getData() { + return data; + } + + }); + } + } catch (AcornAccessVerificationException | IllegalAcornStateException e1) { + throw new ProCoreException(e1); + } + + } + + @Override + public void done() { + + } + + }); + + if(exception instanceof SDBException) throw (SDBException)exception; + else if(exception != null) throw new IllegalAcornStateException(exception); + return false; + } public ServiceLocator getServiceLocator() { diff --git a/bundles/org.simantics.acorn/src/org/simantics/acorn/MainProgram.java b/bundles/org.simantics.acorn/src/org/simantics/acorn/MainProgram.java index 78ff9e899..450ad0618 100644 --- a/bundles/org.simantics.acorn/src/org/simantics/acorn/MainProgram.java +++ b/bundles/org.simantics.acorn/src/org/simantics/acorn/MainProgram.java @@ -250,7 +250,27 @@ public class MainProgram implements Runnable, Closeable { deathBarrier.release(); } } + + static interface MainProgramRunnable { + + public void run() throws Exception; + public void done(); + + } + public Exception runIdle(MainProgramRunnable runnable) { + try { + mutex.acquire(); + runnable.run(); + return null; + } catch (Exception e) { + return e; + } finally { + runnable.done(); + mutex.release(); + } + } + /* * Mutex for streamLRU is assumed here * -- 2.43.2