Commit 0a3ac110 authored by Antti Villberg's avatar Antti Villberg Committed by Tuukka Lehtonen
Browse files

Undo did not wait for pending cluster updates to finish.

refs #6918

Change-Id: I60e8858fa09d69f8793cd5a9c1a3cb20b6682362
(cherry picked from commit 5258d336)
parent 0ae2b770
......@@ -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<Pair<ClusterUID, byte[]>> clusterChanges = new ArrayList<Pair<ClusterUID, byte[]>>();
UndoClusterSupport support = new UndoClusterSupport(clusters);
final int changeSetId = clusters.state.headChangeSetId;
if(ClusterUpdateProcessorBase.DEBUG)
System.err.println(" === BEGIN UNDO ===");
for(int i=0;i<changeSetIds.length;i++) {
final long id = changeSetIds[changeSetIds.length-1-i];
ArrayList<String> ccss = clusters.getChanges(id);
for(int j=0;j<ccss.size();j++) {
String ccsid = ccss.get(ccss.size()-j-1);
try {
if(ClusterUpdateProcessorBase.DEBUG)
System.err.println("performUndo " + ccsid);
performUndo(ccsid, clusterChanges, support);
} catch (DatabaseException e) {
e.printStackTrace();
}
}
}
if(ClusterUpdateProcessorBase.DEBUG)
System.err.println(" === END UNDO ===");
for(int i=0;i<clusterChanges.size();i++) {
final int changeSetIndex = i;
final Pair<ClusterUID, byte[]> 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<Pair<ClusterUID, byte[]>> clusterChanges = new ArrayList<Pair<ClusterUID, byte[]>>();
UndoClusterSupport support = new UndoClusterSupport(clusters);
final int changeSetId = clusters.state.headChangeSetId;
if(ClusterUpdateProcessorBase.DEBUG)
System.err.println(" === BEGIN UNDO ===");
for(int i=0;i<changeSetIds.length;i++) {
final long id = changeSetIds[changeSetIds.length-1-i];
ArrayList<String> ccss = clusters.getChanges(id);
for(int j=0;j<ccss.size();j++) {
String ccsid = ccss.get(ccss.size()-j-1);
try {
if(ClusterUpdateProcessorBase.DEBUG)
System.err.println("performUndo " + ccsid);
performUndo(ccsid, clusterChanges, support);
} catch (DatabaseException e) {
e.printStackTrace();
}
}
}
if(ClusterUpdateProcessorBase.DEBUG)
System.err.println(" === END UNDO ===");
for(int i=0;i<clusterChanges.size();i++) {
final int changeSetIndex = i;
final Pair<ClusterUID, byte[]> 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() {
......
......@@ -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
*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment