package pt.ist.fenixframework.pstm;
import java.util.concurrent.ConcurrentLinkedQueue;
/*
* This class is a generalization of what already existed for keeping
* a record of AlienTransactions (that is, transactions committed on
* another server) so that we keep a record of objects changed that
* should not be garbage-collected.
*
* The same should be done for locally committed transactions,
* because, otherwise, objects changed on a transaction Tn that are
* garbage collected and then read by a later transaction may result
* in having older transactions seeing values from the future.
*
* To see why this may happen, consider the case of three
* transactions, T1, T2, and T3, from oldest to newer, where T2
* changes some object O before T1 accesses it. If O is GCed and T3
* needs to access it, T3 will allocate the object and eventually read
* it, putting the values read in version 0 (that's what VBox.makeNew
* does). If after this T1 accesses O, it will see the value written
* by T2, which is not correct.
*
* By having T2 add a CommitRecord to this class, we will maintain a
* strong reference to O, meaning that it will not be garbage
* collected.
*/
class TransactionCommitRecords {
// CommitRecords that were not GCed yet
private static final ConcurrentLinkedQueue<CommitRecord> COMMIT_RECORDS = new ConcurrentLinkedQueue<CommitRecord>();
static {
Transaction.addTxQueueListener(new jvstm.TxQueueListener() {
public void noteOldestTransaction(int newOldest) {
cleanOldCommitRecords(newOldest);
}
});
}
public static void cleanOldCommitRecords(int txNumber) {
synchronized (COMMIT_RECORDS) {
while ((! COMMIT_RECORDS.isEmpty()) && (COMMIT_RECORDS.peek().txNumber <= txNumber)) {
COMMIT_RECORDS.poll();
}
}
}
public static void addCommitRecord(int txNumber, Object objects) {
COMMIT_RECORDS.offer(new CommitRecord(txNumber, objects));
}
static class CommitRecord {
final int txNumber;
final Object objects;
CommitRecord(int txNumber, Object objects) {
this.txNumber = txNumber;
this.objects = objects; // this is where we keep the strong reference
}
}
}