(defn promise
"Returns a promise object that can be read with deref/@, and set,
once only, with deliver. Calls to deref/@ prior to delivery will
block, unless the variant of deref with timeout is used. All
subsequent derefs will return the same delivered value without
blocking. See also - realized?."
{:added "1.1"
:static true}
[]
(let [d (java.util.concurrent.CountDownLatch. 1)
v (atom d)]
(reify
clojure.lang.IDeref
(deref [_] (.await d) @v)
clojure.lang.IBlockingDeref
(deref
[_ timeout-ms timeout-val]
(if (.await d timeout-ms java.util.concurrent.TimeUnit/MILLISECONDS)
@v
timeout-val))
clojure.lang.IPending
(isRealized [this]
(zero? (.getCount d)))
clojure.lang.IFn
(invoke
[this x]
(when (and (pos? (.getCount d))
(compare-and-set! v d x))
(.countDown d)
this)))))