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,10 +59,14 @@ public class Cluster extends DefaultDisposableImpl implements Disposable {
@Override @Override
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
try {
checkUndisposed("Cluster"); checkUndisposed("Cluster");
dispose(); dispose();
}
finally {
super.finalize(); super.finalize();
} }
}
/** /**
* Creates a connection to a specific database on an <i>FDB</i> cluster. * Creates a connection to a specific database on an <i>FDB</i> cluster.

View File

@ -101,10 +101,14 @@ class FDBDatabase extends DefaultDisposableImpl implements Database, Disposable,
@Override @Override
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
try {
checkUndisposed("Database"); checkUndisposed("Database");
dispose(); dispose();
}
finally {
super.finalize(); super.finalize();
} }
}
@Override @Override
public Transaction createTransaction(Executor e) { public Transaction createTransaction(Executor e) {

View File

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

View File

@ -227,11 +227,11 @@ public class LocalityUtil {
System.err.println("DisposableAsyncIterator not disposed (getBoundaryKeys)"); System.err.println("DisposableAsyncIterator not disposed (getBoundaryKeys)");
} }
} }
catch(Exception e) {} finally {
super.finalize(); super.finalize();
} }
} }
}
private static Charset ASCII = Charset.forName("US-ASCII"); private static Charset ASCII = Charset.forName("US-ASCII");
static byte[] keyServersForKey(byte[] key) { static byte[] keyServersForKey(byte[] key) {

View File

@ -99,9 +99,11 @@ abstract class NativeFuture<T> extends CompletableFuture<T> implements Disposabl
if(ptr != 0) { if(ptr != 0) {
Future_dispose(ptr); Future_dispose(ptr);
if(!isDone()) {
completeExceptionally(new IllegalStateException("Future has been disposed")); completeExceptionally(new IllegalStateException("Future has been disposed"));
} }
} }
}
@Override @Override
public boolean cancel(boolean mayInterruptIfRunning) { public boolean cancel(boolean mayInterruptIfRunning) {
@ -130,7 +132,6 @@ abstract class NativeFuture<T> extends CompletableFuture<T> implements Disposabl
return cPtr; return cPtr;
} }
private native void Future_registerCallback(long cPtr, Runnable callback); private native void Future_registerCallback(long cPtr, Runnable callback);
private native void Future_blockUntilReady(long cPtr); private native void Future_blockUntilReady(long cPtr);
private native boolean Future_isReady(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. inst.context.newTransaction(oldTr); // Other bindings allow reuse of non-retryable transactions, so we need to emulate that behavior.
} }
else { else {
inst.context.updateCurrentTransaction(oldTr, tr); inst.setTransaction(oldTr, tr);
} }
}) })
.thenApply(v -> null); .thenApply(v -> null);

View File

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