ThreadSafeCompoundOperationMap.java
package org.mozilla.javascript;
import java.util.Iterator;
/**
* This class represents a compound operation performed on a thread safe slot map. As each compound
* operation creates a new instance the class itself does not need to consider access by multiple
* threads. This means that the instance fields do not need to be volatile as we are only
* considering access from this thread.
*/
class ThreadSafeCompoundOperationMap extends CompoundOperationMap {
private boolean closed = false;
private long lockStamp = 0;
public ThreadSafeCompoundOperationMap(
SlotMapOwner owner, LockAwareSlotMap map, long lockStamp) {
super(owner);
this.map = map;
this.lockStamp = lockStamp;
}
@Override
public void add(SlotMapOwner owner, Slot newSlot) {
((LockAwareSlotMap) map).addWithLock(owner, newSlot);
touched = true;
}
@Override
public <S extends Slot> S compute(
SlotMapOwner owner, Object key, int index, SlotComputer<S> compute) {
updateMap(true);
S res = ((LockAwareSlotMap) map).computeWithLock(owner, this, key, index, compute);
touched = true;
return res;
}
@Override
public <S extends Slot> S compute(
SlotMapOwner owner,
CompoundOperationMap compoundOp,
Object key,
int index,
SlotComputer<S> compute) {
assert (compoundOp == this);
updateMap(true);
S res = ((LockAwareSlotMap) map).computeWithLock(owner, this, key, index, compute);
touched = true;
return res;
}
@Override
public boolean isEmpty() {
updateMap(false);
return ((LockAwareSlotMap) map).isEmptyWithLock();
}
@Override
public Slot modify(SlotMapOwner owner, Object key, int index, int attributes) {
updateMap(true);
Slot res = ((LockAwareSlotMap) map).modifyWithLock(owner, key, index, attributes);
touched = true;
return res;
}
@Override
public Slot query(Object key, int index) {
updateMap(false);
return ((LockAwareSlotMap) map).queryWithLock(key, index);
}
@Override
public int size() {
updateMap(false);
return ((LockAwareSlotMap) map).sizeWithLock();
}
@Override
public Iterator<Slot> iterator() {
updateMap(false);
return new Iter(map.iterator());
}
@Override
public void close() {
if (!closed) {
((LockAwareSlotMap) owner.getMap()).releaseLock(lockStamp);
closed = true;
}
}
private static class Iter implements Iterator<Slot> {
private final Iterator<Slot> mapIterator;
private Iter(Iterator<Slot> mapIterator) {
this.mapIterator = mapIterator;
}
@Override
public boolean hasNext() {
return mapIterator.hasNext();
}
@Override
public Slot next() {
return mapIterator.next();
}
}
}