diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-07-09 14:28:41 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-07-09 14:28:41 +0000 |
commit | 06be2c38f892fa63a4b53a6700a09e19c6345c54 (patch) | |
tree | df4f0e355c6ed3072e4ac201f0a701507dc0770c | |
parent | 6458d1bc2e1d9ea332c21f0a46e889a59e0b3fff (diff) |
fixed so refs themselves have value semantics
-rw-r--r-- | src/jvm/clojure/lang/TRef.java | 29 |
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; } |