summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-07-09 14:28:41 +0000
committerRich Hickey <richhickey@gmail.com>2007-07-09 14:28:41 +0000
commit06be2c38f892fa63a4b53a6700a09e19c6345c54 (patch)
treedf4f0e355c6ed3072e4ac201f0a701507dc0770c /src
parent6458d1bc2e1d9ea332c21f0a46e889a59e0b3fff (diff)
fixed so refs themselves have value semantics
Diffstat (limited to 'src')
-rw-r--r--src/jvm/clojure/lang/TRef.java29
1 files changed, 15 insertions, 14 deletions
diff --git a/src/jvm/clojure/lang/TRef.java b/src/jvm/clojure/lang/TRef.java
index b05815b0..b813eb5f 100644
--- a/src/jvm/clojure/lang/TRef.java
+++ b/src/jvm/clojure/lang/TRef.java
@@ -17,11 +17,11 @@ import java.util.concurrent.atomic.AtomicReference;
public class TRef<T> extends AFn{
//reference to a chain of TVals, only the head of which may be non-committed
final AtomicReference<TVal> tvals;
-volatile InheritableThreadLocal dvals;
+final AtomicReference<InheritableThreadLocal> dvals;
public TRef(){
this.tvals = new AtomicReference<TVal>();
- this.dvals = null;
+ this.dvals = new AtomicReference<InheritableThreadLocal>();
}
public TRef(T initVal){
@@ -50,28 +50,28 @@ public T val() throws Exception{
}
final Binding getThreadBinding(){
- if(dvals != null)
- return (Binding) dvals.get();
+ InheritableThreadLocal dv = dvals.get();
+ if(dv != null)
+ return (Binding) dv.get();
return null;
}
public void pushThreadBinding(T val){
- if(dvals == null)
+ InheritableThreadLocal dv = dvals.get();
+ if(dv == null)
{
- synchronized(this)
- {
- if(dvals == null)
- dvals = new InheritableThreadLocal();
- }
+ dvals.compareAndSet(null, new InheritableThreadLocal());
+ dv = dvals.get();
}
- dvals.set(new Binding(val, (Binding) dvals.get()));
+ dv.set(new Binding(val, (Binding) dv.get()));
}
public void popThreadBinding() throws Exception{
+ InheritableThreadLocal dv = dvals.get();
Binding b;
- if(dvals == null || (b = (Binding) dvals.get()) == null)
+ if(dv == null || (b = (Binding) dv.get()) == null)
throw new Exception("Can't pop unbound ref");
- dvals.set(b.rest);
+ dv.set(b.rest);
}
public T set(T val) throws Exception{
@@ -99,7 +99,8 @@ public void touch() throws Exception{
}
boolean isBound(){
- return (dvals != null && dvals.get() != null)
+ InheritableThreadLocal dv = dvals.get();
+ return (dv != null && dv.get() != null)
||
getCurrentTVal() != null;
}