Skip to content

Commit 3765092

Browse files
committed
Add concurrent.clj
1 parent 62c515e commit 3765092

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
;; Copyright (c) Rich Hickey and contributors. All rights reserved.
2+
;; The use and distribution terms for this software are covered by the
3+
;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+
;; which can be found in the file epl-v10.html at the root of this distribution.
5+
;; By using this software in any fashion, you are agreeing to be bound by
6+
;; the terms of this license.
7+
;; You must not remove this notice, or any other, from this software.
8+
9+
(ns ^{:skip-wiki true}
10+
clojure.core.async.impl.concurrent
11+
(:import [System.Threading Thread ThreadStart])) ;;; [java.util.concurrent ThreadFactory]
12+
13+
(set! *warn-on-reflection* true)
14+
15+
16+
;;;(defn counted-thread-factory
17+
;;; "Create a ThreadFactory that maintains a counter for naming Threads.
18+
;;; name-format specifies thread names - use %d to include counter
19+
;;; daemon is a flag for whether threads are daemons or not
20+
;;; opts is an options map:
21+
;;; init-fn - function to run when thread is created"
22+
;;; ([name-format daemon]
23+
;;; (counted-thread-factory name-format daemon nil))
24+
;;; ([name-format daemon {:keys [init-fn] :as opts}]
25+
;;; (let [counter (atom 0)]
26+
;;; (reify
27+
;;; ThreadFactory
28+
;;; (newThread [_this runnable]
29+
;;; (let [body (if init-fn
30+
;;; (fn [] (init-fn) (.run ^Runnable runnable))
31+
;;; runnable)
32+
;;; t (Thread. ^Runnable body)]
33+
;;; (doto t
34+
;;; (.setName (format name-format (swap! counter inc)))
35+
;;; (.setDaemon daemon))))))))
36+
37+
38+
;;; DM: Added this type to match java.util.concurrent.ThreadFactory
39+
40+
(defprotocol ThreadFactory
41+
"Protocol to match java.util.concurrent.ThreadFactory"
42+
(newThread [_ runnable] "create a new thread"))
43+
44+
;;; In ClojureJVM, an IFn is a Runnable. Not so in ClojureCLR.
45+
;;; We take in something callable, but have to wrap it as a ThreadStart delegate.
46+
47+
(defn counted-thread-factory
48+
"Create a ThreadFactory that maintains a counter for naming Threads.
49+
name-format specifies thread names - use %d to include counter
50+
daemon is a flag for whether threads are daemons or not
51+
opts is an options map:
52+
init-fn - function to run when thread is created"
53+
([name-format daemon]
54+
(counted-thread-factory name-format daemon nil))
55+
([name-format daemon {:keys [init-fn] :as opts}]
56+
(let [counter (atom 0)]
57+
(reify
58+
ThreadFactory
59+
(newThread [_this runnable]
60+
(let [body (if init-fn
61+
(gen-delegate ThreadStart [] (init-fn) runnable)
62+
(gen-delegate ThreadStart [] runnable))
63+
t (Thread. ^ThreadStart body)]
64+
(doto t
65+
(.set_Name (format name-format (swap! counter inc)))
66+
(.set_IsBackground daemon))))))))
67+
68+
(defonce
69+
^{:doc "Number of processors reported by the JVM"}
70+
processors Environment/ProcessorCount) ;;; (.availableProcessors (Runtime/getRuntime))
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
;; Copyright (c) Rich Hickey and contributors. All rights reserved.
2+
;; The use and distribution terms for this software are covered by the
3+
;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+
;; which can be found in the file epl-v10.html at the root of this distribution.
5+
;; By using this software in any fashion, you are agreeing to be bound by
6+
;; the terms of this license.
7+
;; You must not remove this notice, or any other, from this software.
8+
9+
(ns clojure.core.async.concurrent-test
10+
(:require [clojure.test :refer :all]
11+
[clojure.core.async.impl.concurrent :as conc])
12+
(:import [System.Threading Thread]
13+
[clojure.core.async.impl.concurrent ThreadFactory])) ;;; [java.util.concurrent ThreadFactory]
14+
15+
(deftest test-counted-thread-factory
16+
(testing "Creates numbered threads"
17+
(let [^clojure.core.async.impl.concurrent.ThreadFactory factory (conc/counted-thread-factory "foo-%d" true)
18+
threads (repeatedly 3 #(.newThread factory (constantly nil)))]
19+
(is (= ["foo-1" "foo-2" "foo-3"] (map #(.Name ^Thread %) threads)))))) ;;; .getName

0 commit comments

Comments
 (0)