Skip to content

Commit c4e1551

Browse files
committed
simplifying io-thread impl
1 parent e477c08 commit c4e1551

File tree

1 file changed

+25
-37
lines changed

1 file changed

+25
-37
lines changed

src/main/clojure/clojure/core/async.clj

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -468,49 +468,37 @@ to catch and handle."
468468
(defonce ^:private ^ExecutorService io-thread-exec
469469
(Executors/newCachedThreadPool (conc/counted-thread-factory "io-thread-macro-%d" true)))
470470

471-
(defmacro io-thread
472-
"Asynchronously executes the body in a thread compatible with I/O workload,
473-
returning immediately to the calling thread. Only blocking operations should
474-
be used in io-thread bodies.
471+
(defn thread-call
472+
"Executes f in another thread, returning immediately to the calling
473+
thread. Returns a channel which will receive the result of calling
474+
f when completed, then close."
475+
([f] (thread-call f thread-macro-executor))
476+
([f ^ExecutorService exec]
477+
(let [c (chan 1)]
478+
(let [binds (Var/getThreadBindingFrame)]
479+
(.execute exec
480+
(fn []
481+
(Var/resetThreadBindingFrame binds)
482+
(try
483+
(let [ret (f)]
484+
(when-not (nil? ret)
485+
(>!! c ret)))
486+
(finally
487+
(close! c))))))
488+
c)))
475489

476-
io-thread bodies should not (either directly or indirectly) perform operations
477-
that never block nor run pure compute operations. Parking ops
478-
(i.e. <!, >! and alt!/alts!) used in io-thread bodies will throw at
490+
(defmacro io-thread
491+
"Asynchronously executes the body in a thread intended for I/O
492+
workloads, returning immediately to the calling thread.
493+
io-thread bodies may (either directly or indirectly) perform
494+
operations that may block indefinitely. Parking ops (i.e. <!,
495+
>! and alt!/alts!) used in io-thread bodies will throw at
479496
runtime.
480497
481498
Returns a channel which will receive the result of the body when
482499
completed"
483500
[& body]
484-
`(let [c# (chan 1)
485-
captured-bindings# (Var/getThreadBindingFrame)]
486-
(.execute ^ExecutorService @#'io-thread-exec
487-
(^:once fn* []
488-
(Var/resetThreadBindingFrame captured-bindings#)
489-
(try
490-
(let [result# (do ~@body)]
491-
(when-not (nil? result#)
492-
(>!! c# result#)))
493-
(finally
494-
(close! c#)))))
495-
c#))
496-
497-
(defn thread-call
498-
"Executes f in another thread, returning immediately to the calling
499-
thread. Returns a channel which will receive the result of calling
500-
f when completed, then close."
501-
[f]
502-
(let [c (chan 1)]
503-
(let [binds (Var/getThreadBindingFrame)]
504-
(.execute thread-macro-executor
505-
(fn []
506-
(Var/resetThreadBindingFrame binds)
507-
(try
508-
(let [ret (f)]
509-
(when-not (nil? ret)
510-
(>!! c ret)))
511-
(finally
512-
(close! c))))))
513-
c))
501+
`(thread-call (^:once fn* [] ~@body) @#'io-thread-exec))
514502

515503
(defmacro thread
516504
"Executes the body in another thread, returning immediately to the

0 commit comments

Comments
 (0)