summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2009-06-12 16:55:14 -0400
committerRich Hickey <richhickey@gmail.com>2009-06-12 16:55:14 -0400
commit1a0e23d0e78ef3d3a3a6267a68adcfc414d3fb56 (patch)
treed48a698ec784713c29af2450edfd425169224cef /src
parenta9cb831fe714966e225a5297ef844513fe4a373a (diff)
added more future fns, fixed print of pending futures, added promise/deliver
Diffstat (limited to 'src')
-rw-r--r--src/clj/clojure/core.clj42
-rw-r--r--src/clj/clojure/core_print.clj2
2 files changed, 43 insertions, 1 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index da282d35..4c76d9b5 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -4023,6 +4023,14 @@
Defaults to true")
+(defn future?
+ "Returns true if x is a future"
+ [x] (instance? java.util.concurrent.Future x))
+
+(defn future-done?
+ "Returns true if future f is done"
+ [#^java.util.concurrent.Future f] (.isDone f))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; helper files ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(alter-meta! (find-ns 'clojure.core) assoc :doc "Fundamental library of the Clojure language")
(load "core_proxy")
@@ -4052,6 +4060,15 @@
not yet finished, calls to deref/@ will block."
[& body] `(future-call (fn [] ~@body)))
+
+(defn future-cancel
+ "Cancels the future, if possible."
+ [#^java.util.concurrent.Future f] (.cancel f true))
+
+(defn future-cancelled?
+ "Returns true if future f is cancelled"
+ [#^java.util.concurrent.Future f] (.isCancelled f))
+
(defn pmap
"Like map, except f is applied in parallel. Semi-lazy in that the
parallel computation stays ahead of the consumption, but doesn't
@@ -4131,3 +4148,28 @@
(str "-" q))
(when (:interim *clojure-version*)
"-SNAPSHOT")))
+
+(defn promise
+ "Experimental.
+ Returns a promise object that can be read with deref/@, and set,
+ once only, with deliver. Calls to deref/@ prior to delivery will
+ block. All subsequent derefs will return the same delivered value
+ without blocking."
+ []
+ (let [d (java.util.concurrent.CountDownLatch. 1)
+ v (atom nil)]
+ (proxy [clojure.lang.AFn clojure.lang.IDeref] []
+ (deref [] (.await d) @v)
+ (invoke [x]
+ (locking d
+ (if (pos? (.getCount d))
+ (do (.countDown d)
+ (reset! v x)
+ this)
+ (throw (IllegalStateException. "Multiple deliver calls to a promise"))))))))
+
+(defn deliver
+ "Experimental.
+ Delivers the supplied value to the promise, releasing any pending
+ derefs. A subsequent call to deliver on a promise will throw an exception."
+ [promise val] (promise val))
diff --git a/src/clj/clojure/core_print.clj b/src/clj/clojure/core_print.clj
index 228b8cb3..d2b1612e 100644
--- a/src/clj/clojure/core_print.clj
+++ b/src/clj/clojure/core_print.clj
@@ -312,6 +312,6 @@
(print-sequential (format "#<%s@%x: "
(.getSimpleName (class o))
(System/identityHashCode o))
- pr-on, "", ">", (list @o), w))
+ pr-on, "", ">", (list (if (and (future? o) (not (future-done? o))) :pending @o)), w))
(def #^{:private true} print-initialized true)