If a (mutable) Java collection that exposes it's backing array is passed to c.c/sort in multiple threads, the collection will be concurrently modified in multiple threads.
`
user=> (def q (java.util.concurrent.ArrayBlockingQueue. 1))
'user/q
user=> (future (loop [] (.add q 1) (.remove q 1) (recur)))
object[clojure.core$future_call$reify__4393 0x4769b07b {:status :pending, :val nil}]
user=> (take 3 (distinct (repeatedly #(sort q))))
((1) () nil)
`
Approach: Convert coll to a seq before converting it to an array, thus preserving the original collection.
Patch: 0001-CLJ-1763-make-sort-thread-safe.patch
Alternate approaches:
- Document in sort that, like Java arrays, Java collections backed by arrays are modified in-place.
- Change RT.toArray() to defensively copy the array returned from a (non-IPersistentCollection) Java collection. This has a number of potential ramifications as this method is called from several paths.
- For non-Clojure collections, could also use Collections.sort() instead of dumping to array and using Arrays.sort().