Skip to content

Commit 9cedea3

Browse files
committed
Add a new-thread-fn parameter
1 parent 2e0d49d commit 9cedea3

File tree

2 files changed

+56
-30
lines changed

2 files changed

+56
-30
lines changed

src/manifold/executor.clj

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -32,44 +32,42 @@
3232
(finally
3333
(.set executor-thread-local executor#)))))
3434

35-
(defn- make-thread-fn
36-
[thread-class]
37-
(eval `(fn ([group# target# name#]
38-
(new ~thread-class group# target# name#))
39-
([group# target# name# stack-size#]
40-
(new ~thread-class group# target# name# stack-size#)))))
35+
(defn- ^Thread new-thread
36+
([group target name]
37+
(Thread. group target name))
38+
([group target name stack-size]
39+
(Thread. group target name stack-size)))
4140

42-
(defn thread-factory
43-
"Returns a `java.util.concurrent.ThreadFactory`.
41+
(defn ^ThreadFactory thread-factory
42+
"Returns a `java.util.concurrent.ThreadFactory`.
4443
4544
|:---|:----
4645
| `name-generator` | a zero-argument function, which, when invoked returns the name of the `java.lang.Thread` that will be created. |
4746
| `executor-promise` | a promise eventually containing a `java.util.concurrent.Executor` that will be stored on `manifold.executor/executor-thread-local`. |
4847
| `stack-size` | the desired stack size for the new thread, or nil/zero to indicate that this parameter is to be ignored. |
4948
| `daemon?` | marks the created threads as either daemon or user threads. The Java Virtual Machine exits when the only threads running are all daemon threads. |
50-
| `thread-class` | a `java.lang.Class` that extends `java.lang.Thread` which defines the created threads. |"
51-
^ThreadFactory
49+
| `new-thread-fn` | a three/four arguments function which returns an implementation of `java.lang.Thread` when called. |"
5250
([name-generator executor-promise]
53-
(thread-factory name-generator executor-promise nil true Thread))
51+
(thread-factory name-generator executor-promise nil true nil))
5452
([name-generator executor-promise stack-size]
55-
(thread-factory name-generator executor-promise stack-size true Thread))
53+
(thread-factory name-generator executor-promise stack-size true nil))
5654
([name-generator executor-promise stack-size daemon?]
57-
(thread-factory name-generator executor-promise stack-size daemon? Thread))
58-
([name-generator executor-promise stack-size daemon? thread-class]
59-
(let [make-thread (make-thread-fn thread-class)]
60-
(reify ThreadFactory
61-
(newThread [_ runnable]
62-
(let [name (name-generator)
63-
curr-loader (.getClassLoader (class thread-factory))
64-
f #(do
65-
(.set executor-thread-local @executor-promise)
66-
(.run ^Runnable runnable))]
67-
(doto
68-
(if stack-size
69-
^Thread (make-thread nil f name stack-size)
70-
^Thread (make-thread nil f name))
71-
(.setDaemon daemon?)
72-
(.setContextClassLoader curr-loader))))))))
55+
(thread-factory name-generator executor-promise stack-size daemon? nil))
56+
([name-generator executor-promise stack-size daemon? new-thread-fn]
57+
(let [new-thread (or new-thread-fn new-thread)]
58+
(reify ThreadFactory
59+
(newThread [_ runnable]
60+
(let [name (name-generator)
61+
curr-loader (.getClassLoader (class thread-factory))
62+
f #(do
63+
(.set executor-thread-local @executor-promise)
64+
(.run ^Runnable runnable))
65+
thread (if stack-size
66+
^Thread (new-thread nil f name stack-size)
67+
^Thread (new-thread nil f name))]
68+
(doto thread
69+
(.setDaemon daemon?)
70+
(.setContextClassLoader curr-loader))))))))
7371

7472
;;;
7573

test/manifold/executor_test.clj

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,39 @@
3232
(let [num-threads (atom 0)
3333
in-thread-loader (promise)
3434
tf (e/thread-factory
35-
#(str "my-loader-prefix-" (swap! num-threads inc))
36-
(deliver (promise) nil))
35+
#(str "my-loader-prefix-" (swap! num-threads inc))
36+
(deliver (promise) nil))
3737
executor (Executors/newFixedThreadPool 1 ^ThreadFactory tf)]
3838
(.execute ^ExecutorService executor
3939
(fn []
4040
(let [l (clojure.lang.RT/baseLoader)]
4141
(deliver in-thread-loader l))))
4242
(is (instance? clojure.lang.DynamicClassLoader @in-thread-loader))))
43+
44+
(defn- ^ThreadFactory thread-factory
45+
([] (thread-factory nil))
46+
([new-thread-fn] (thread-factory new-thread-fn nil))
47+
([new-thread-fn stack-size]
48+
(let [num-threads (atom 0)
49+
tf (e/thread-factory
50+
#(str "my-pool-prefix" (swap! num-threads inc))
51+
(deliver (promise) nil)
52+
stack-size
53+
false
54+
new-thread-fn)]
55+
tf)))
56+
57+
(deftest test-thread-factory
58+
(let [tf (thread-factory)]
59+
(.newThread tf (constantly nil)))
60+
(let [tf (thread-factory
61+
(fn [group target _]
62+
(proxy [Thread] [group target "custom-name"])))
63+
thread (.newThread tf (constantly nil))]
64+
(is (= "custom-name" (.getName thread))))
65+
(let [tf (thread-factory
66+
(fn [group target _ stack-size]
67+
(proxy [Thread] [group target "custom-name" stack-size]))
68+
500)
69+
thread (.newThread tf (constantly nil))]
70+
(is (= "custom-name" (.getName thread)))))

0 commit comments

Comments
 (0)