Skip to content

Commit 8c0d9e2

Browse files
[track-state] Synchronize access to WeakHashMap cache
1 parent 891e57a commit 8c0d9e2

File tree

2 files changed

+21
-17
lines changed

2 files changed

+21
-17
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## master (unreleased)
44

5+
* [#939](https://github.com/clojure-emacs/cider-nrepl/pull/939): Tracker: synchronize access to WeakHashMap cache to prevent infinite loops.
6+
57
## 0.55.6 (2025-04-28)
68

79
* Bump `orchard` to [0.34.3](https://github.com/clojure-emacs/orchard/blob/master/CHANGELOG.md#0343-2025-04-28).

src/cider/nrepl/middleware/track_state.clj

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@
6969
(defn- get-metadata-if-changed?
7070
[^Var the-var, ^WeakHashMap real-metadata-ns-cache]
7171
(let [var-name (.sym the-var)
72-
;; WHM is not thread-safe but we should only access this from a single
73-
;; (session) thread.
7472
cached-meta (some-> real-metadata-ns-cache (.get var-name))
7573
current-meta (meta the-var)]
7674
(when-not (identical? cached-meta current-meta)
@@ -116,23 +114,27 @@
116114
[the-ns]
117115
(let [ns-sym (ns-name the-ns)
118116
old-project-ns-map (:interns (get *old-project-state* ns-sym))
119-
real-metadata-whm (when *real-metadata-cache*
117+
real-metadata-whm (if *real-metadata-cache*
120118
(or (@*real-metadata-cache* ns-sym)
121119
((swap! *real-metadata-cache* assoc ns-sym
122-
(WeakHashMap.)) ns-sym)))]
123-
(reduce-kv (fn [acc sym the-var]
124-
(if (and (var? the-var)
125-
(not (identical? (.ns ^Var the-var)
126-
clojure-core)))
127-
(let [old-meta (get old-project-ns-map sym)
128-
new-meta (compute-var-meta the-var real-metadata-whm
129-
old-project-ns-map)]
130-
(if (identical? old-meta new-meta)
131-
acc
132-
(assoc acc sym new-meta)))
133-
acc))
134-
old-project-ns-map
135-
(ns-map the-ns))))
120+
(WeakHashMap.)) ns-sym))
121+
(WeakHashMap.))]
122+
;; WHM is not thread-safe, so synchronize the access to it to avoid infinite
123+
;; loops like https://github.com/clojure-emacs/cider-nrepl/issues/936.
124+
(locking real-metadata-whm
125+
(reduce-kv (fn [acc sym the-var]
126+
(if (and (var? the-var)
127+
(not (identical? (.ns ^Var the-var)
128+
clojure-core)))
129+
(let [old-meta (get old-project-ns-map sym)
130+
new-meta (compute-var-meta the-var real-metadata-whm
131+
old-project-ns-map)]
132+
(if (identical? old-meta new-meta)
133+
acc
134+
(assoc acc sym new-meta)))
135+
acc))
136+
old-project-ns-map
137+
(ns-map the-ns)))))
136138

137139
(def clojure-core-map
138140
(when clojure-core

0 commit comments

Comments
 (0)