@@ -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