From bac37b91230d8e4ab3a1e6042a6e8c4b7e9cbf53 Mon Sep 17 00:00:00 2001
From: Max Penet <m@qbits.cc>
Date: Sun, 18 Nov 2012 13:27:25 +0100
Subject: [PATCH] Allow to specify an Executor instance to be used with
 future-call

---
 src/clj/clojure/core.clj |   59 +++++++++++++++++++++++++---------------------
 1 file changed, 32 insertions(+), 27 deletions(-)

diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 099100c..d3881f6 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -6243,35 +6243,40 @@
     (.write w (str content))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; futures (needs proxy);;;;;;;;;;;;;;;;;;
-(defn future-call 
-  "Takes a function of no args and yields a future object that will
-  invoke the function in another thread, and will cache the result and
-  return it on all subsequent calls to deref/@. If the computation has
-  not yet finished, calls to deref/@ will block, unless the variant
-  of deref with timeout is used. See also - realized?."
+(defn future-call
+  "Takes a function of no args (and optionally an ExecutorService
+  instance that will run the task) and yields a future
+  object that will invoke the function in another thread, and will
+  cache the result and return it on all subsequent calls to
+  deref/@. If the computation has not yet finished, calls to deref/@
+  will block, unless the variant of deref with timeout is used. See
+  also - realized?."
   {:added "1.1"
    :static true}
-  [f]
-  (let [f (binding-conveyor-fn f)
-        fut (.submit clojure.lang.Agent/soloExecutor ^Callable f)]
-    (reify 
-     clojure.lang.IDeref 
-     (deref [_] (.get fut))
-     clojure.lang.IBlockingDeref
-     (deref
-      [_ timeout-ms timeout-val]
-      (try (.get fut timeout-ms java.util.concurrent.TimeUnit/MILLISECONDS)
-           (catch java.util.concurrent.TimeoutException e
-             timeout-val)))
-     clojure.lang.IPending
-     (isRealized [_] (.isDone fut))
-     java.util.concurrent.Future
-      (get [_] (.get fut))
-      (get [_ timeout unit] (.get fut timeout unit))
-      (isCancelled [_] (.isCancelled fut))
-      (isDone [_] (.isDone fut))
-      (cancel [_ interrupt?] (.cancel fut interrupt?)))))
-  
+  ([f executor]
+     (let [f (binding-conveyor-fn f)
+           fut (.submit ^java.util.concurrent.ExecutorService executor
+                        ^Callable f)]
+       (reify
+         clojure.lang.IDeref
+         (deref [_] (.get fut))
+         clojure.lang.IBlockingDeref
+         (deref
+           [_ timeout-ms timeout-val]
+           (try (.get fut timeout-ms java.util.concurrent.TimeUnit/MILLISECONDS)
+                (catch java.util.concurrent.TimeoutException e
+                  timeout-val)))
+         clojure.lang.IPending
+         (isRealized [_] (.isDone fut))
+         java.util.concurrent.Future
+         (get [_] (.get fut))
+         (get [_ timeout unit] (.get fut timeout unit))
+         (isCancelled [_] (.isCancelled fut))
+         (isDone [_] (.isDone fut))
+         (cancel [_ interrupt?] (.cancel fut interrupt?)))))
+  ([f]
+     (future-call f clojure.lang.Agent/soloExecutor)))
+
 (defmacro future
   "Takes a body of expressions and yields a future object that will
   invoke the body in another thread, and will cache the result and
-- 
1.7.10

