summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2011-04-03 12:39:13 -0400
committerRich Hickey <richhickey@gmail.com>2011-04-03 12:39:13 -0400
commit57c5186972c9c0f03d4bb5d2445309f14405e098 (patch)
tree61fafa0a5d2ce04f943062b6c88fea322bd09454
parent8fda34e4c77cac079b711da59d5fe49b74605553 (diff)
made promises lock-free, updates after first no-ops, not exceptions
-rw-r--r--src/clj/clojure/core.clj17
1 files changed, 8 insertions, 9 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 4a6f7761..0c411dd1 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -5985,7 +5985,7 @@
:static true}
[]
(let [d (java.util.concurrent.CountDownLatch. 1)
- v (atom nil)]
+ v (atom d)]
(reify
clojure.lang.IDeref
(deref [_] (.await d) @v)
@@ -5997,15 +5997,14 @@
timeout-val))
clojure.lang.IPending
(isRealized [this]
- (= 0 (.getCount d)))
+ (zero? (.getCount d)))
clojure.lang.IFn
- (invoke [this x]
- (locking d
- (if (pos? (.getCount d))
- (do (reset! v x)
- (.countDown d)
- this)
- (throw (IllegalStateException. "Multiple deliver calls to a promise"))))))))
+ (invoke
+ [this x]
+ (when (and (pos? (.getCount d))
+ (compare-and-set! v d x))
+ (.countDown d)
+ this)))))
(defn deliver
"Alpha - subject to change.