summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jvm/clojure/lang/LockingTransaction.java8
-rw-r--r--src/jvm/clojure/lang/Ref.java41
2 files changed, 38 insertions, 11 deletions
diff --git a/src/jvm/clojure/lang/LockingTransaction.java b/src/jvm/clojure/lang/LockingTransaction.java
index 093ad2d6..8ee7678d 100644
--- a/src/jvm/clojure/lang/LockingTransaction.java
+++ b/src/jvm/clojure/lang/LockingTransaction.java
@@ -437,9 +437,11 @@ public static void main(String[] args){
for(Ref tref : items)
{
//Transaction.get().doTouch(tref);
- LockingTransaction t = LockingTransaction.getEx();
- int val = (Integer) t.doGet(tref);
- t.doSet(tref, val + 1);
+// LockingTransaction t = LockingTransaction.getEx();
+// int val = (Integer) t.doGet(tref);
+// t.doSet(tref, val + 1);
+ int val = (Integer) tref.get();
+ tref.set(val + 1);
}
return null;
}
diff --git a/src/jvm/clojure/lang/Ref.java b/src/jvm/clojure/lang/Ref.java
index 6c1f9bcd..6e2e3351 100644
--- a/src/jvm/clojure/lang/Ref.java
+++ b/src/jvm/clojure/lang/Ref.java
@@ -55,20 +55,21 @@ public static class TVal{
final static AtomicLong ids = new AtomicLong();
-TVal tvals;
-
-AtomicInteger faults;
+TVal tvals;
+final AtomicInteger faults;
transient volatile InheritableThreadLocal<Binding> dvals;
final ReentrantReadWriteLock lock;
LockingTransaction.Info tinfo;
final long id;
+transient volatile Object cached;
public Ref(){
this.tvals = null;
this.dvals = null;
this.tinfo = null;
faults = new AtomicInteger();
+ this.cached = faults; //use faults as magic never-been-set value
lock = new ReentrantReadWriteLock();
id = ids.getAndIncrement();
}
@@ -78,7 +79,31 @@ public Ref(Object initVal){
tvals = new TVal(initVal, 0, System.currentTimeMillis());
}
-//ok out of transaction
+//not necessarily the latest val
+
+// ok out of transaction
+public Object cachedVal(){
+ Binding b = getThreadBinding();
+ if(b != null)
+ return b.val;
+ if(cached != faults)
+ return cached;
+ try
+ {
+ lock.readLock().lock();
+ if(tvals != null)
+ return cached = tvals.val;
+ throw new IllegalStateException(this.toString() + " is unbound.");
+ }
+ finally
+ {
+ lock.readLock().unlock();
+ }
+}
+
+//the latest val
+
+// ok out of transaction
public Object currentVal(){
Binding b = getThreadBinding();
if(b != null)
@@ -87,7 +112,7 @@ public Object currentVal(){
{
lock.readLock().lock();
if(tvals != null)
- return tvals.val;
+ return cached = tvals.val;
throw new IllegalStateException(this.toString() + " is unbound.");
}
finally
@@ -125,11 +150,11 @@ public void popThreadBinding() throws Exception{
//*
//must be dynamically bound or transactional read
-public Object val() throws Exception{
+public Object get() throws Exception{
Binding b = getThreadBinding();
if(b != null)
return b.val;
- return LockingTransaction.getEx().doGet(this);
+ return cached = LockingTransaction.getEx().doGet(this);
}
public Object set(Object val) throws Exception{
@@ -186,7 +211,7 @@ void trimHistory(){
final public IFn fn(){
- return (IFn) currentVal();
+ return (IFn) cachedVal();
}
public Object invoke() throws Exception{