@Override public <T> void setBoxValue(VBox<T> vbox, T value) { vbox.body = VBox.makeNewBody(value, number, null); // we immediately // clean old unused // values }
public VBoxBody<?> commit(E newValue, int txNumber) { VBoxBody<E> currentHead = this.body; VBoxBody<E> existingBody = null; if (currentHead != null) { existingBody = currentHead.getBody(txNumber); // Commented by FMC@17-09-2012 => it causes a crash in JVM for // transactional classes that inherit fom the VBox and loaded // during the bootstrap. // assert(existingBody == null || existingBody.version <= txNumber); } if (existingBody == null || existingBody.version < txNumber) { VBoxBody<E> newBody = makeNewBody(newValue, txNumber, currentHead); existingBody = CASbody(currentHead, newBody); } // return the existingBody, regardless of whether the CAS succeeded return existingBody; }
protected VBoxBody<E> CASbody(VBoxBody<E> expected, VBoxBody<E> newValue) { /* In the pure JVSTM the CAS can only fail because another thread already committed this value. However, when used together with Fenix Framework, it is possible that the body changes because of reloads. We identify this by testing whether our commit did make it (this.body.version must be >= newValue.version). If not, we retry the CAS.*/ while (true) { if (UNSAFE.compareAndSwapObject(this, Offsets.bodyOffset, expected, newValue)) { return newValue; } else { // if the CAS failed the new value must already be there unless FenixFramework was doing a reload! // update expected expected = this.body; if (expected.version < newValue.version) { // update the tail newValue = makeNewBody(newValue.value, newValue.version, expected); // retry continue; } else { return this.body.getBody(newValue.version); } } } }
@Override public <T> void setBoxValue(VBox<T> vbox, T value) { VBoxBody<T> body = vbox.body; if ((body != null) && (body.version == this.number)) { /* * If the head of the versioned history corresponds to the body * created by this transaction then there is no chance of this * object being reverted. */ body.value = value; } else { VBoxBody<T> newBody; if(body == null){ newBody = VBox.makeNewBody(value, number, vbox instanceof VBoxAom? new VBoxBody<T>(vbox.replicate(), 0, null) : null); }else{ newBody = VBox.makeNewBody(value, number, body); } this.vboxesWrittenBack = this.vboxesWrittenBack.cons(vbox); /* * We must prevent from concurrent reversions * The following CAS of the VBoxAom retries if the object has been reverted. */ vbox.CASbody(body, newBody); // vbox.body = newBody; } }