isDone check in NativeFuture.dispose, try/finally for finalizers, some rewriting of stack tester context transaction management.
This commit is contained in:
parent
f456c67bda
commit
570b60fe53
|
@ -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.
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue