isDone check in NativeFuture.dispose, try/finally for finalizers, some rewriting of stack tester context transaction management.

This commit is contained in:
A.J. Beamon 2017-12-06 13:06:57 -08:00
parent f456c67bda
commit 570b60fe53
8 changed files with 50 additions and 28 deletions

View File

@ -59,9 +59,13 @@ public class Cluster extends DefaultDisposableImpl implements Disposable {
@Override
protected void finalize() throws Throwable {
checkUndisposed("Cluster");
dispose();
super.finalize();
try {
checkUndisposed("Cluster");
dispose();
}
finally {
super.finalize();
}
}
/**

View File

@ -101,9 +101,13 @@ class FDBDatabase extends DefaultDisposableImpl implements Database, Disposable,
@Override
protected void finalize() throws Throwable {
checkUndisposed("Database");
dispose();
super.finalize();
try {
checkUndisposed("Database");
dispose();
}
finally {
super.finalize();
}
}
@Override

View File

@ -555,9 +555,13 @@ class FDBTransaction extends DefaultDisposableImpl implements Disposable, Transa
@Override
protected void finalize() throws Throwable {
checkUndisposed("Transaction");
dispose();
super.finalize();
try {
checkUndisposed("Transaction");
dispose();
}
finally {
super.finalize();
}
}
@Override

View File

@ -227,9 +227,9 @@ public class LocalityUtil {
System.err.println("DisposableAsyncIterator not disposed (getBoundaryKeys)");
}
}
catch(Exception e) {}
super.finalize();
finally {
super.finalize();
}
}
}

View File

@ -99,7 +99,9 @@ abstract class NativeFuture<T> extends CompletableFuture<T> implements Disposabl
if(ptr != 0) {
Future_dispose(ptr);
completeExceptionally(new IllegalStateException("Future has been disposed"));
if(!isDone()) {
completeExceptionally(new IllegalStateException("Future has been disposed"));
}
}
}
@ -130,7 +132,6 @@ abstract class NativeFuture<T> extends CompletableFuture<T> implements Disposabl
return cPtr;
}
private native void Future_registerCallback(long cPtr, Runnable callback);
private native void Future_blockUntilReady(long cPtr);
private native boolean Future_isReady(long cPtr);

View File

@ -418,7 +418,7 @@ public class AsyncStackTester {
inst.context.newTransaction(oldTr); // Other bindings allow reuse of non-retryable transactions, so we need to emulate that behavior.
}
else {
inst.context.updateCurrentTransaction(oldTr, tr);
inst.setTransaction(oldTr, tr);
}
})
.thenApply(v -> null);

View File

@ -101,20 +101,19 @@ abstract class Context implements Runnable {
}
public synchronized void updateCurrentTransaction(Transaction tr) {
Context.transactionRefCounts.putIfAbsent(tr, new AtomicInteger(1));
releaseTransaction(Context.transactionMap.put(this.trName, tr));
Context.transactionRefCounts.computeIfAbsent(tr, x -> new AtomicInteger(1));
releaseTransaction(Context.transactionMap.put(this.trName, tr));
}
public synchronized boolean updateCurrentTransaction(Transaction oldTr, Transaction newTr) {
Context.transactionRefCounts.putIfAbsent(newTr, new AtomicInteger(1));
if(Context.transactionMap.replace(this.trName, oldTr, newTr)) {
AtomicInteger count = Context.transactionRefCounts.computeIfAbsent(newTr, x -> new AtomicInteger(0));
count.incrementAndGet();
releaseTransaction(oldTr);
return true;
}
else {
Context.transactionRefCounts.remove(newTr);
return false;
}
return false;
}
public void newTransaction() {
@ -131,12 +130,8 @@ abstract class Context implements Runnable {
public synchronized void switchTransaction(byte[] trName) {
this.trName = ByteArrayUtil.printable(trName);
Transaction tr = db.createTransaction();
Context.transactionRefCounts.put(tr, new AtomicInteger(1));
Transaction previousTr = Context.transactionMap.putIfAbsent(this.trName, tr);
if(previousTr != null) {
releaseTransaction(tr);
}
Transaction tr = Context.transactionMap.computeIfAbsent(this.trName, x -> db.createTransaction());
Context.transactionRefCounts.computeIfAbsent(tr, x -> new AtomicInteger(1));
}
abstract void executeOperations() throws Throwable;

View File

@ -86,6 +86,20 @@ class Instruction extends Stack {
}
}
void setTransaction(Transaction oldTr, Transaction newTr) {
if(!isDatabase) {
context.updateCurrentTransaction(oldTr, newTr);
this.tr = context.getCurrentTransaction();
if(isSnapshot) {
readTr = this.tr.snapshot();
}
else {
readTr = tr;
}
}
}
void releaseTransaction() {
context.releaseTransaction(this.tr);
}